I've got a Symfony 5.1 (fullstack) application and I'm using Api Platform. Now I want to use API tokens to access the API (using Custom Authentication System with Guard), but already logged in users should be able to access the API without a token.
I've used the example from the Symfony documentation about Multiple Guard Authenticators and added a second authenticator:
$container->loadFromExtension('security', [
// ...
'firewalls' => [
'api' => [
'context' => 'my_context',
'pattern' => '^/api',
'guard' => [
'entry_point' => LoginFormAuthenticator::class,
'authenticators' => [
LoginFormAuthenticator::class,
ApiTokenAuthenticator::class,
],
],
],
'default' => [
'context' => 'my_context',
'anonymous' => true,
'lazy' => true,
'guard' => [
'authenticators' => [
LoginFormAuthenticator::class,
],
],
],
],
);
When I use TokenAuthenticator as the entry_point, requests to ^/api/ are not accessible by logged in users. They'll get a 401 Unauthorized ("A Token was not found in the TokenStorage.").
When I use ApiTokenAuthenticator as the entry_point, (XMLHttp-)requests to ^/api/ are redirected to /login instead of a 401 Unauthorized.
How can I have API endpoints that are accessible by both authenticators?
Edit: Thanks to Cerad, I've added context to both firewalls, as described here. Didn't make any difference.
Related
I'm trying to send VoIP push notifications through the Firebase. I uploaded a *.p8 file to my project in the Firebase Console and now have an APNs Auth Key displayed there.
My alarm push notifications are delivered without any problems:
'apns' => [
'headers' => [
'apns-push-type' => ‘alarm',
],
...
But when I try to change the type to voip I get an error:
'apns' => [
'headers' => [
'apns-push-type' => 'voip',
'apns-topic' => ‘com.mycompany.myapp.voip'
],
...
Firebase response:
#errors: array:1 [
"error" => array:4 [
"code" => 400
"message" => "Request contains an invalid argument."
"status" => "INVALID_ARGUMENT"
"details" => array:2 [
0 => array:2 [
"#type" => "type.googleapis.com/google.firebase.fcm.v1.FcmError"
"errorCode" => "INVALID_ARGUMENT"
]
1 => array:2 [
"#type" => "type.googleapis.com/google.rpc.BadRequest"
"fieldViolations" => array:1 [
0 => array:2 [
"field" => "message.token"
"description" => "Invalid registration token"
]
]
]
]
]
]
Any ideas? Am I missing something important?
The situation at the date (16/03/2020): No, Firebase Cloud Messaging doesn't support APNS VoIP push notifications, but it's planned.
The official Firebase support answer:
Currently, VoIP push is not supported by FCM. However, we're aware that a lot of developers like you want this, so there's already a feature request filed for this. As of now, we are yet to find out any details or timelines as to when it will be implemented. You can check our release notes from time to time for any updates about Firebase features and its services.
I am new in Laravel Passport and I am able to get the the tokens from Laravel like below with Postman.
With this token, I tried to access my api route user-details
Route::group(['middleware'=>'auth:api'],function(){
Route::get('user-details','ApiController#getUsers');
});
Here I am getting
{
"error": "Unauthenticated."
}
Screenshot:
What is the issue actually ?
Since you didn't mention this step, I am guessing you might have missed this step.
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
Read the documentation fully.
https://laravel.com/docs/5.5/passport
Using aws/aws-sdk-php 3.21.6. I must be misunderstanding how ReturnValues works when a ConditionExpression meets the ConditionalCheckFailedException error.
What I'm hoping is that if the ConditionExpression fails, which in turn triggers the ConditionalCheckFailedException, that I can catch this exception and then get access via ReturnValues to the new Attributes from DD.
The docs Attributes I'm expecting from ReturnValues seem to imply this.
From testing, however, ReturnValues only returns Attributes if the ConditionExpression is true, not when it fails.
$response = $client->updateItem([
'TableName' => 'MyTable',
'Key' => [
'customer_url' => [
'S' => 'someurl.com'
],
'customer_platform' => [
'S' => 'some_platform'
]
],
'ExpressionAttributeNames' => [
'#C' => 'createdAt'
],
'ExpressionAttributeValues' => [
':val1' => [
'S' => '2017-01-24T14:15:32'
],
':val2' => [
'S' => '2017-01-24T14:15:30'
]
],
'UpdateExpression' => 'set #C = :val1',
'ConditionExpression' => '#C = :val2', // :val2 originally was 2017-01-24T14:15:30, before attempting to update to 2017-01-24T14:15:32. If I change the field to 2017-01-24T14:15:31, before running this update it will throw the ConditionalCheckFailedException
'ReturnValues' => 'ALL_NEW'
]);
Yes, ReturnValues is populated only if an updateItem succeeds. If it fails, because of ConditionalCheckFailedException or any other reason, ReturnValues will be null.
Supporting documentation from here, with emphasis mine:
Use ReturnValues if you want to get the item attributes as they appeared either before or after they were updated.
I want to create a plugin to use zend-i18n/translate on controller. On zf2 I have a controller plugin that does this for me, but on zf3 I could not get this to work. How can I use zend-i18n inside a controller or via controller plugin with zf3?
==========
I just found what I need here on zf doc: https://docs.zendframework.com/zend-mvc-i18n/services/#mvctranslator-and-translatorfactory
if you already have config the translator as factory on your module.config.php, you can inject on your controller plugin.
You can virtually do the same as the answer that #hkulekci referred to in his comment.
'service_manager' => [
'factories' => [
\Zend\I18n\Translator\TranslatorInterface::class => \Zend\I18n\Translator\TranslatorServiceFactory::class,
]
]
and
'controller_plugins' => [
'invokables' => [
'translate' => \Zend\I18n\View\Helper\Translate::class
]
]
After that you can get the translate plugin like in your controller action methods like this:
public someAction(){
$translator = $this->translate;
}
Check the Zend Framework documentation or this Zend Framework blog for more details on the controller plugin manager.
For translate in model and controller, I did this in my module.config.php
'service_manager' => [
'factories' => [
\Zend\I18n\Translator\Translator::class => \Zend\I18n\Translator\TranslatorServiceFactory::class,
],
],
Then from my controller or model which has serviceContainer initialised I do:
$this->myVar = $serviceContainer->get(\Zend\I18n\Translator\Translator::class);
Then I can access it by doing
$this->myVar->translate('lorem ipsum');
I create my first app with silex. Only logged in users can use the app. In the first page i create a login form, so the user can authenticate. My security provider look like:
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'security.firewalls' => array(
'secure_area_edison' => array(
'pattern' => '^/admin/',
'form' => array('login_path' => '/', 'check_path' => '/admin/login_check'),
'logout' => array('logout_path' => '/admin/logout', 'invalidate_session' => true),
'users' => function () use ($app) {
return new App\Services\UserProvider($app['db']);
},
),
)
));
Every url after '/admin' require that the user was successfull authenticated. Everything works fine and now i want to extend my app with an API. I create a new controller which retrieves data from database and return a JSON reponse, this work also fine.
But how can the user authenticate for this API? Should i create a new column in my user table like "hash" or "token"? Users which will retrieve the JSON Response must send the token in every get request, is this the correct way?
The url can look:
/admin/api/allProducts/token/<TOKEN>
you should use token base authentication instead of passing token in every get request.
refer : https://github.com/thcolin/silex-simpleuser-jwt