FOSOAuthServerBundle - How to get User in a controller - php

I implemented FOSOAuthServerBundle in my application to provide an API for mobile application. It seems to work, the user gets the Token and also the RefreshToken but if I make the controller require the user object that always returns null. Also fails the control of the permission, which is only IS_AUTHENTICATED_ANONIMOUSLY.
example:
public function showUserAction(){
$user = $this->getUser()
//$user = null
$auth = $this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')
//$auth = false
}
How to get the user object in a controller with this type of authentication?

Based on your comment you have created client with different grant_types.
NOTE: If you use grant_type=client_credentials during authentication, there is no User available since you do not specify exact user/password for generating token. In case of grant_type=password you pass username & password and token is linked to user in this case. Hope this makes sense.

Try this:
$user = $this->get('security.token_storage')->getToken()->getUser();

Related

Laravel - Get the Authenticated users

I have a navbar where I try to display some stuff depending if the user is authenticated or not.
So I have a login form, when I axios.post('/login') with the email / password, and I deal with the potential errors.
I have also a method in my UserController to get the authenticated user (if there is one) via Auth::user() like the docs says, but this methods always returns an empty object ...
public function getUser() {
$user = Auth::user();
Log::info($user);
return $user;
}
This methods always returns me a [2018-06-17 16:29:26] local.INFO:
But the stranger things (like the TV show) is where I try to go on my '/admin' routes, my middleware use also the 'Auth::user()' to determines if the user's role is 'user' or 'admin', that 'Auth::user()' methods returns me well the user ...
I am stuck ...
Please, if someone has experienced the same issue, let me know how to solve it, or if someone want to see more code, let me know as well I'll be glad to show you more proof.
Thanks,
public function getUser() {
$user = Auth::user()->name;
return $user;
}
Use Auth::user()->name; to return your user name on navbar.
You have to provide further info to Log::info(), Something like the name or id of the $user->name, $user->id.
Further more you can use that id, Search with it and get the info of the user.
You should have a proper pattern for the log, By pattern i means proper logging. Passing the whole object $user will not work.
Hello you must use this syntax on laravel version 8 and more
auth('api')->user()->id
api will be used when you have an api if you are on a web version you will use
auth('web')->user()->id

Symfony token getCredentials returns null

I created a way to authenticate a user with API keys, thanks to a class A implementing the SimplePreAuthenticatorInterface interface. Everything works well (the user is successfully authenticated).
I'm trying to store the API keys, for a later use during the user's journey. To do so, inside the authenticate method of my class A, I return a PreAuthenticatedToken in which the credentials are my API keys.
The problem is : Inside a custom service, when I try to get the token credentials, I get null... I successfully get the API keys when I comment the line 76 of the PreAuthenticatedToken Symfony core class :
public function eraseCredentials()
{
parent::eraseCredentials();
//$this->credentials = null;
}
My questions are:
1) Why is the method eraseCredentials called whereas the user is authenticated? I thought this method was called during user's logging out...
2) What am I doing wrong? Is the PreAuthenticatedToken token the right place to store my API keys? How can I get them back from a custom service ?
Thanks for helping me. :)
PS : I'm a newbee on posting in Stackoverflow (and in English ^^). Sorry in advance for any mistakes.
I found another similar question but it has no helping response and I added some more precisions.
EDIT: The code of my custom service where I try to get the credentials is:
$token = $this->container->get("security.token_storage")->getToken();
if ($token !== null) {
$credentials = $token->getCredentials();
// $credentials is null here
}
EDIT 2: The return part in my code of my SimplePreAuthenticatorInterface::authenticateToken method :
return new PreAuthenticatedToken(
$user,
$apiKeys,
$providerKey,
$user->getRoles()
);
Ad 1. It depends on your AuthenticationProviderManager: this class accepts $eraseCredentials as second parameter - by default set to true (here).
That's why eraseCredentials method is being called on PreAuthenticatedToken $token during authenication (here).
Ad 2. Please check How to Authenticate Users with API Keys tutorial. You should create your custom ApiKeyAuthenticator class and add logic there.
According to your comment:
Note that authenticateMethod from tutorial is being called inside authenticate method (here). At that time token credentials are not erased yet and you can access them. For security reason they are erased after authentication (but this can also be changed / configured via security.yml file). If you need them later you can introduce custom token class and store API key there.

Lumen - Non token-based authenthication?

I trying to use lumen for the first time to create a restful backend service.
I'm used to working with laravel but with lumen I'm already stuck at the autentication. I can't find any tutorials on this.
I'm not even sure if my logic is secure for this. Bassically I receive a post request which contains an email and a password, then I want to check if the details are correct etc and authenticate the user.
I feel like I'm missing something, is this something that lumes comes with standard or will I need to rewrite the Auth service
It seems to be in the documentation you linked.
$this->app['auth']->viaRequest('api', function ($request) {
// Return User or null...
});
The Request class is passed in to this function. You would need to grab the email and password out of it $request->get('email') and request->get('password'), check to make sure they are valid.
I'm not sure of the best way to do this with Lumen or how much is available so to make it easy, you could just do something like the following...
$this->app['auth']->viaRequest('api', function ($request) {
$email = $request->get('email');
$password = $request->get('password');
$user = \DB::table('users')->where('email', $email)->first();
// Invalid Email
if ($user === null) {
return null;
}
// Check if password matches
if ( \Hash::check($user->password, $password) ) {
return $user;
}
// Invalid password
return null;
});
Keep in mind Lumen does not support session state you would need to pass in the email and password for every request. However, once it's setup, all you need to do in Lumen is use Auth::user() to grab the user.
You could also use jwt-auth which uses JSON Web Tokens which also makes it fairly easy and allows you to not pass emails and password around.
https://github.com/tymondesigns/jwt-auth
For anyone who encounters this problem. This is how i solved it:
In the auth serviceProvider (boot method) you check if there is a authorization header present. If there is one, it should include a apiToken, witch you can validate and continue with the normal flow.
If there is no Authorization header present, you can check the request variable for a email and password. Validate the login, and on success you save a new apiToken. I returned this token to the frontend, and made a feature that handles all ajax request, to include this token in the header. I also implemented a function that handles every response in my frontend application witch checks for a 401, when its there redirect to the login page.
With this aproach, you can use both auth methods, and Auth::user() is available through your application. Just make sure the login page is not handled with the Auth middleware!

Trying to Authenticate user without password in Laravel

I am trying to implement the login without password in laravel application but it shows an error: Argument 1 passed to Illuminate\Auth\SessionGuard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable, string given
And the code i am using is:
$checkUser = 'manish.arora4926#gmail.com';
Auth::login($checkUser, true);
Please help me to resolve this issue.
Considering your email column name is email, try
$user = User::whereEmail('manish.arora4926#gmail.com')->first();
Auth::login($user)
or
Auth::loginUsingId($user->id);
If you need to log an existing user instance into your application, you may call the login method with the user instance. The given object must be an implementation of the Illuminate\Contracts\Auth\Authenticatable contract. Of course, the App\User model included with Laravel already implements this interface:
$checkUser must be eloquent instance. so you need to access eloquent before authenticate user
$checkUser=App\User::where('email','manish.arora4926#gmail.com')->first();
Auth::login($checkUser, true);
in case you know id of user just using login using id
Auth::loginUsingId(1);
// Login and "remember" the given user...
Auth::loginUsingId(1, true);

Setting Symfony2 security.context User data after login

Using Symfony2 I want to augment the security.content user after login with information obtained after login.
So in the login success code I do the following in AccountController:
$user = $this->get('security.context')->getToken()->getUser();
// Get everything we'll ever need for this user
$user->fillDetails($this, $this->container);
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
// Give it to the security context
$this->container->get('security.context')->setToken($token);
return $this->redirect($this->generateUrl('AccountBundle_homepage'));
If I immediately retrieve the user again after calling setToken() this information that is set in the User object in fillDetails() is still present.
However in the controller action for AccountBundle_homepage when I get the user using
$user = $this->get('security.context')->getToken()->getUser();
The extra information I set in fillDetails() is no longer there, or 0.
Any help appreciated.
The security context creates a token on each request, that means you can't modify a token, redirect the user and expect getting data set on the previous token. If you don't persist your user, it won't work. The user is reloaded on each request too.
You can find more information about the token here: http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html#the-token

Categories