laravel8 jwt多用户认证

  1. 本文只用作记录

一、下载jwt

github.com/tymondesigns/jwt-auth/w...
composer require tymon/jwt-auth

发布配置文件

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

二、生成jwt秘钥

php artisan jwt:secret 

三、配置guard

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
        ],

        'admin' => [
            'driver' => 'jwt',
            'provider' => 'admins'
        ]
    ],

四、配置providers

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

         'admins' => [
             'driver' => 'eloquent',
             'model' => App\Models\Admin::class,
         ],
    ],

五、生成jwt 中间件

php artisan make:middleware JWTRoleAuth 

六、配置jwt中间件

use Closure;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class JWTRoleAuth
{
    public function handle($request, Closure $next)
    {
        try {
            if (! $user = JWTAuth::parseToken()->authenticate()) {  //获取到用户数据,并赋值给$user
                return response()->json([
                    'code' => 1004,
                    'message' => '无此用户'

                ], 404);
            }
            return $next($request);

        } catch (TokenExpiredException $e) {

            return response()->json([
                'code' => 1003,
                'message' => 'token 过期' ,
            ]);

        }  catch (TokenInvalidException $e) {
            return response()->json([
                'code' => 1002,
                'message' => 'token 无效',
            ]);

        } catch (JWTException $e) {

            return response()->json([
                'code' => 1001,
                'message' => '缺少token' ,
            ]);
        }
    }
}

七、编辑模型

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;


class Admin extends Authenticatable implements JWTSubject
{
    use HasFactory, Notifiable;

    protected $table="admins";


    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * 获取会储存到 jwt 声明中的标识
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * 返回包含要添加到 jwt 声明中的自定义键值对数组
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return ["role"=>"admin"];
    }
}

八 、编写代码测试

如果你是api auth:api
如果你是admin auth:admin

use App\Http\Controllers\Controller;
use App\Service\Api\RegisterService;
use Illuminate\Http\Request;

class LoginController extends Controller
{

    /**
     * @var RegisterService
     */

    private $registerService;

    /**
     * LoginController constructor.
     * @param RegisterService $registerService
     */
    public function __construct(RegisterService  $registerService)
    {
        $this->registerService = $registerService;
        $this->middleware("auth:api",['except' => ['login', 'register',"logout"]]);
    }

    public function register(Request $request)
    {
        $name = $request->input("name");

        $email = $request->input("email");

        $password = $request->input("password");

        $data = $this->registerService->register($name,$email,$password);

        if ($data){
            return $this->success("0",$data,"注册成功");
        } else {
            return $this->error("425",$data,"注册失败");
        }

    }

    public function login(Request $request)
    {
        $credentials = request(['name', 'password']);

        if (! $token = auth("api")->attempt($credentials)) {
            $this->error("0",[],"登录失败");
        }

        return $this->success("1",$this->respondWithToken($token),"登录成功");
    }

    /**
     * Refresh a token.
     * 刷新token,如果开启黑名单,以前的token便会失效。
     * 值得注意的是用上面的getToken再获取一次Token并不算做刷新,两次获得的Token是并行的,即两个都可用。
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->success('0',$this->respondWithToken(auth('api')->refresh()),'刷新成功');
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ]);
    }

    /**
     * 用户退出登录
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth('api')->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    public function me()
    {
        $data = auth("api")->user();
        return $this->success("0",$data,"查询成功");
    }
}

九、测试

测试注册

测试登录

测试我的信息

测试登出

十、我的环境是

php7.4.16 + nginx1.19.8 + mysql8.0.23 + laravel8.34.0

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 5

大佬,你RegisterService的写法是不是忘记贴出来了 :stuck_out_tongue_winking_eye:

2年前 评论
人生起落寻常事,花开花谢皆是春 (楼主) 2年前

return $token = auth("api")->attempt($credentials); 获取不到。 但是cookies里面有。

2年前 评论

JWTAuth::parseToken()->authenticate()他会去查user表,但是我不是user表,应该怎么办?

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!