jwt refresh doesn't update custom claims - php

This question has been asked many times, but decent solution couldn't be found.
I do this - $newToken = auth()->refresh();
in my custom claims, I have
public function getJWTCustomClaims()
{
return [
'is_verified' => $this->verified,
'email' => $this->email,
'role' => $this->getMainRole()->name
];
}
Scenario - first, when I login, it returns me the jwt token. in that jwt token, I have is_verified , email, role set. Let's say is_verified was 0 at the time i got the token. Now, I changed it to 1 in database. NOw when I refrehs the token, as I showed you above, returned jwt token still has is_verified equal to 0, but it should have 1. Any idea how to fix it?

Try with $newToken = auth()->refresh(false, true);
Second parameter is "reset claims":
JWTGuard class -
public function refresh($forceForever = false, $resetClaims = false)

Related

Laravel value of variable will not hold

I never saw this before. Hopefully I can explain it to you that you'll understand it.
My code:
$google2fa = app(Google2FA::class);
$secret = $google2fa->generateSecretKey();
$user = $this->verifyToken('authentication', $request->mail, $secret);
$g2faUrl = $google2fa->getQRCodeUrl(
'name',
$request->mail,
$user['google_authentication']
);
$writer = new Writer(
new ImageRenderer(
new RendererStyle(400),
new ImagickImageBackEnd()
)
);
$qrcode_image = base64_encode($writer->writeString($g2faUrl));
return view('auth.register.admin.index', ['qrcode' => '', 'secret' => $user['google_authentication']]);
Above you see the array variable: $user['google_authentication'] on the first part I create a secret token, then I save the secret in the verify method verifyToken().
When I publish this secret on the view, it shows me a different secret then that i saved. But the weird part is, when I place a var_dump() in the code, then the secret in the view is the same as I saved.
The verify method just do a simple post api request to my middleware where I save the secret under the user, nothing special.
What is wrong in here?
The view doesn't load twice, I already checked Laravel debug bar
And why does it hold the value of the variable ($user['google_authentication']) when I use var_dump() in the code.

Laravel 5.1 and Socialite Questions

This isn't a post about a problem I'm having right now. I'm planning on using the Laravel Socialite plugin in my App, I already have a fully working login/register system using Laravel's built in Auth system but I'm wondering if there is a good way to allow users that already have their accounts in my app to link their social profiles to the already existing account?
The plan would be that they can login with their username and password or any of their social profiles. All the research I've done so far explains how to set up Socialite and utilise that data for registering/logging in new users, however I can't find anything to marry the two together.
I'm not looking for anyone to write this for me so please don't get confused by this post.
Thanks for any info,
Andy
Absolutely.
I have FB and Twitter OAuth on one site. The way I do it is by adding oauth_facebook_id and oauth_twitter_id columns to the users table (as well as an avatar column, if you want that).
I have the routes set up as /auth/{provider} and /auth/{provider}/callback, so /auth/facebook and /auth/facebook/callback for example.
In my handleProviderCallback($provider) method on my AuthController, I grab the returned user's details and check to see if they already exist in my database with their email, Facebook OAuth ID or Twitter OAuth ID. If they exist, I set their email, OAuth IDs and their avatar, if they don't exist I create them. Then I log them in.
$user = Socialite::driver($provider)->user();
$user_query = User::where('email', $user->email)
->orWhere('oauth_facebook_id', $user->id)
->orWhere('oauth_twitter_id', $user->id)
->get();
if($user_query->count() > 0) {
$the_user = $user_query->first();
if($provider === 'facebook') {
$the_user->oauth_facebook_id = $user->id;
}
if($provider === 'twitter') {
$the_user->oauth_twitter_id = $user->id;
}
$the_user->avatar = $user->avatar;
$the_user->save();
\Auth::login($the_user, true);
return redirect('/');
}
$new_user = User::create([
'name' => $user->name,
'email' => $user->email,
'oauth_facebook_id' => $provider === 'facebook' ? $user->id : NULL,
'oauth_twitter_id' => $provider === 'twitter' ? $user->id : NULL,
'avatar' => $user->avatar
]);
\Auth::login($new_user, true);
return redirect('/');
Hopefully this helps you make sense of how to do it.

Yii2 Logout Specific User

How can I tell yii2 to logged out specific user who has login to system?
Let say, there is 2 user is logged in on system, userA and userB.
How can I specified logged out userB?
What I know is userB has to trigger this command to logout.
Yii::$app->user->logout();
return $this->goHome();
But maybe we can use some command like Yii::$app->user->logout('userB');?
Or is it has some other way?
Well, the problem is about how to kill all sessions of the user.
Flag user to force relogin
You can add an additional column force_relogin to User identity class and set it to true when you need to logout someone:
$user = User::findByLogin('userB');
$user->force_logout = 1;
$user->save();
Then add the event handler beforeLogin() on user component like so:
'user' => [
'class' => 'yii\web\User',
'on beforeLogin' => function ($event) {
if ($event->identity->force_logout && $event->cookieBased) {
$event->isValid = false;
}
},
'on afterLogin' => function ($event) {
if ($event->identity->force_logout) {
$event->identity->force_logout = false;
$event->identity->save();
}
}
]
Check, whether $cookieBased and $identity->force_logout are so on...
But that's a bad idea, because the user may have more than one session (logged in in different browsers)
Store list user's sessions in DB
Create table user_sessions with user_id and session_id columns and save each session, you open for that user in the DB. That you can find all sessions of the user and drop them one by one. Something like: (code is not tested, just as an idea)
$sessionId = Yii::$app->session->getId();
session_commit();
foreach (UserSessions::findByUserLogin('userB') as $session) {
session_id($session->id);
session_start();
session_destroy();
session_commit();
}
session_id($sessionId); // Restore original session
session_start();
session_commit();
The idea is weak because you always should take care about consistence of sessions on the server and in the DB.
Store sessions in DB
Store sessions is the database, as described in the Yii2 Guide for Session handling
Then you can just find session in the DB and delete it directly. You shouldn't take care about the consistence and session rotation, because DB is the only place, where the sessions are being stored. As a free bonus you get a non-blocking work with sessions.
If you are still looking for a solution to this, just change the auth_key of the user that you want to logout. This auth_key is used by the system to remember if a user is logged in, thus changing this will invalidate any session that uses this key.
Example to logout a user with id=100
$user = User::findOne(100);
$user->generateAuthKey(); //a function in User (Identity) class that generates the auth_key
$user->save();
If you are using a model User for storing auth credentials, you can simply change the value of 'id' (and also a key '100') to some other integer value, to make user fail auth on his next request.
In other words, you must change all '100', for example to '200' in this code:
file: /models/User.php
private static $users = [
'100' => [
'id' => '100',
'username' => 'admin',
'password' => 'password_for_admin',
'authKey' => '43e02a0f0e5f6a7907b2f2c69a765be7',
'accessToken' => '7b2f2c69a765be743e02a0f0e5f6a790',
],
];

Laravel OAuth2 - Password Grant

I am trying to build a RESTful API, I am using Lumen and I set up lucadegasperi's Laravel Oauth2 - Password Grant.
In Postman, I am posting 5 parameters:
grant_type => password
client_id => 123
client_secret = abc
username => testuser
password => secret
And in response, I receive an access_token successfully. However, in the end-user scenario, where there are 2 form fields (username and password) only, it doesn't seem logical to place client_id, client_secret and grant_type as hidden fields and post them from there. So should I hard-code these 3 parameters (grant_type and valid client_id and client_secret in the Controller where I validate username and password? It feels wrong too. Where should I put it? What is the optimum way of using it?
This is my verify() function:
public function verify($username, $password)
{
$credentials = [
'username' => $username,
'password' => $password,
];
if (Auth::once($credentials)) {
return Auth::user()->id;
}
return false;
}

Laravel API Auth class usage

Trying to build and API based on laravel that aims to grow to intense usage by lots of clients. My question is whether there are serious drawbacks of using Auth class in my code ?
I have implemented the OAuth2 authorization, and to get info about the user that is making the request I have a filter :
Route::filter('hasAccess', function($request)
{
//get the cleaned token string
$auth_code = Request::header('Authorization');
$auth_code = trim(preg_replace('/Bearer/sui', "", $auth_code));
//get the stored session and put the query in cache for 10 minutes
$ts = DB::table('sessions as s')
->leftJoin('oauth_session_access_tokens as osat', 's.token', '=', 'osat.id')
->select('s.*')
->where('osat.access_token', '=', $auth_code)
->remember(10, $auth_code)
->first();
//Auth user cross-app
Auth::onceUsingId($ts->user);
//Extract the requested action
$request = $request->getAction();
$request = $request['controller'];
$parts = explode('#', $request);
$required = strtolower($parts[0]).'.'.$parts[1];
$required = preg_replace('/controller/sui', "", $required);
//Get the permissions
$permissions = json_decode($ts->permissions, true);
$permissions = array_fetch($permissions,'name');
if (!in_array($required,$permissions))
{
return Response::json([
'error' => true,
'dataset' => 'You don\'t have rights to access this url'
]);
}
});
It validates the user access rights to the controller action, but the most interesting in it is the row with Auth::onceUsingId($ts->user);. This rows authorizez the user for only 1 request. Also if any other ways to get info about user exist, please mention them. Thanks
You talk about 'serious drawbacks' of using Auth class code - but you dont really explain drawbacks compared to what? Just manually looking in the database yourself for the user?
All the Auth::onceUsingId() is doing is logging your user into the application without a session or cookie. This is perfect for an API - as you dont normally have persistence between requests.
You can then do Auth::user() to get data about the user, such as Auth::user()->name.

Categories