Search code examples
laraveloctobercmsoctobercms-pluginsjwt

set user rainlab last login timestamp by JWTAuth


I have managed to create jwtauth to connect my mobile app to octobercms backend from this reference but the last_login field is always empty, I believe this is not set by default. this is authenticated function that I have

use Tymon\JWTAuth\JWTAuth;

public function __construct(JWTAuth $auth)
{
    $this->auth = $auth;
}

public function authenticate(Request $request)
{
    try {
        if (! $token = $this->auth->attempt($request->only('email', 'password'))) {
            return response()->json([
                'errors' => [
                    'root' => 'Could not sign you in with those details.',
                ],
            ], 401);
        }
    } catch (JWTException $e) {
        return response()->json([
            'errors' => [
                'root' => 'Failed.',
            ],
        ], $e->getStatusCode());
    }

    return response()->json([
        'data' => $request->user(),
        'meta' => [
            'token' => $token,
        ],
    ]);
} 

it's called by this route.php from jwtauth folder

Route::group(['prefix' => 'api'], function () {
Route::post('auth/login','Autumn\JWTAuth\Http\Controllers\AuthController@authenticate');
Route::post('auth/register', 'Autumn\JWTAuth\Http\Controllers\AuthController@register');
Route::post('auth/logout', 'Autumn\JWTAuth\Http\Controllers\AuthController@logout');    

Route::group(['middleware' => 'jwt.auth'], function () {
    Route::get('auth/me', 'Autumn\JWTAuth\Http\Controllers\AuthController@user');        
});    

how do we set user last_login timestamp? I hope my question is clear to understand.

added plugin.php where i extended user plugin as requested by @HardikSatasiya since i got exception implementing his suggestion

use System\Classes\PluginBase;
use Rainlab\User\Controllers\Users as UsersController;
use Rainlab\User\Models\User as UserModels;
use Event;

class Plugin extends PluginBase
{
  public function registerComponents()
  {
  }

  public function registerSettings()
  {
  }

  public function boot()
  {
    UserModels::extend(function($model){

        $model->bindEvent('model.beforeSave',function() use ($model) {

            $users = \BackendAuth::getUser();               
            $model->backend_users_id = $users->id;              
            //above line result exception when calling method as @HardikSatasiya suggested          
            if(!empty($model->avatar)){
                $model->image_path = $model->avatar->getPath();
            }
            if(!empty($model->groups)){
                $model->membership = $model->groups[0]['name'];
            }
        });

        $model->addJsonable('users_detail','membership');
    }); 



    UsersController::extendFormFields(function($form,$model,$context){

        $form->addTabFields([
            'users_detail[0][gender]' => [
                'label' => 'Jenis Kelamin',
                'span' => 'left',
                'tab' => 'User Profile',
                'type' => 'radio',
                'options' => [
                    'Pria' => 'Pria',
                    'Wanita' => 'Wanita'
                ] 
            ],
            'users_detail[0][ttl]' => [
                'label' => 'Tempat/Tanggal Lahir',
                'type' => 'text',
                'span' => 'left',
                'tab' => 'User Profile'
            ],           
        ]);  
    });
  }

i add additional fields to user table by this separate plugin..


Solution

  • Ok, may be because internal hooks are not called when this plugin externally logsin user.

    May be we need to call it manually, this code snippet can do it, just put given code after successful login.

    // this will fire hooks and update `last_login`
    // get authenticated user from the jwt authmanager
    $user = $this->auth->authenticate($token);
    $user->afterLogin();
    

    Added in your code below.

    public function authenticate(Request $request)
    {
        try {
            if (! $token = $this->auth->attempt($request->only('email', 'password'))) {
                return response()->json([
                    'errors' => [
                        'root' => 'Could not sign you in with those details.',
                    ],
                ], 401);
            }
        } catch (JWTException $e) {
            return response()->json([
                'errors' => [
                    'root' => 'Failed.',
                ],
            ], $e->getStatusCode());
        }
    
        // this will fire hooks and update `last_login`
        // get authenticated user from the jwt authmanager
        $user = $this->auth->authenticate($token);
        $user->afterLogin();
        // ^ this code
    
        return response()->json([
            'data' => $request->user(),
            'meta' => [
                'token' => $token,
            ],
        ]);
    }
    

    this snippet will update last_login as expected. i did not test it but it will work as it should.

    if any doubt or problem please comment.