Laravel 使用 JWT 完成多用户认证

版权声明:科比龙篮 https://blog.csdn.net/qq_36514588/article/details/82186617

JWT ------ json web Token

作用:

1.降低耦合性,适用于前后端分离,分布式架构,取代传统的session

2.较少服务器和数据库的压力

JWT的结构

JWT包含了使用.分隔的三部分: Header 头部 Payload 负载 Signature 签名 结构为 Header.Payload.Signature

Header

在header中通常包含了两部分:token类型和采用的加密算法。{ "alg": "HS256", "typ": "JWT"} 接下来对这部分内容使用 Base64Url 编码组成了JWT结构的第一部分。

Payload

Token的第二部分是负载,它包含了claim, Claim是一些实体(通常指的用户)的状态和额外的元数据,有三种类型的claim:reserved,public 和 private.Reserved claims: 这些claim是JWT预先定义的,在JWT中并不会强制使用它们,而是推荐使用,常用的有 iss(签发者),exp(过期时间戳), sub(面向的用户), aud(接收方), iat(签发时间)。 Public claims:根据需要定义自己的字段,注意应该避免冲突 Private claims:这些是自定义的字段,可以用来在双方之间交换信息 负载使用的例子:{ "sub": "1234567890", "name": "John Doe", "admin": true} 上述的负载需要经过Base64Url编码后作为JWT结构的第二部分。

Signature

创建签名需要使用编码后的header和payload以及一个秘钥,使用header中指定签名算法进行签名。例如如果希望使用HMAC SHA256算法,那么签名应该使用下列方式创建: HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 签名用于验证消息的发送者以及消息是没有经过篡改的。 完整的JWT 完整的JWT格式的输出是以. 分隔的三段Base64编码,与SAML等基于XML的标准相比,JWT在HTTP和HTML环境中更容易传递。 下列的JWT展示了一个完整的JWT格式,它拼接了之前的Header, Payload以及秘钥签名

例如:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjUsImlzcyI6Imh0dHA6Ly93d3cubGFyYXZlbGp3dC5jb20vYXBpL2xvZ2luIiwiaWF0IjoxNTM1NTMwMTY1LCJleHAiOjE1MzU1MzM3NjUsIm5iZiI6MTUzNTUzMDE2NSwianRpIjoieHk1bXlTRTN3RE16Sm1DaCJ9.6DVuASwFvnN-y2mkCeF89_75jcFXSpffkEvI_e8sAa8

开始使用

安装扩展

composer require tymon/jwt-auth

编辑 config/app.php

providers 中添加
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,

aliases 添加

 'JWTAuth'=> Tymon\JWTAuth\Facades\JWTAuth::class,
 'JWTFactory'=> Tymon\JWTAuth\Facades\JWTFactory::class

发布JWT的配置文件

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

生成JWT Key

php artisan jwt:generate

创建中间件解决跨域问题(无需跨域可以省去此步奏)

php artisan make:middleware CORS

编辑 app/Http/Middleware/CORS.php

<?php

namespace App\Http\Middleware;

use Closure;

class CORS
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        //解决跨域问题
        header('Access-Control-Allow-Origin: *');

        $headers = [
            'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
        ];
        if($request->getMethod() == "OPTIONS") {
            return Response::make('OK', 200, $headers);
        }

        $response = $next($request);
        foreach($headers as $key => $value)
            $response->header($key, $value);
        return $response;
    }
}

注册中间件  ----编辑app/Http/Kernel.php

创建中间件验证token

php artisan make:middleware User\authJWT

编辑 app/Http/Middleware/authJWT.php

<?php

namespace App\Http\Middleware;

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

class authJWT
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        \Config::set('jwt.user' , "App\Models\Admin");
        \Config::set('auth.providers.users.model', \App\Models\Admin::class);
        try {
            if (!$user = JWTAuth::toUser(JWTAuth::getToken())){
                return response()->json([
                    'errcode' => 400004,
                    'errmsg' => '无此用户'
                ], 404);
            }

        } catch (TokenExpiredException $e) {

            return response()->json([
                'errcode' => 400001,
                'errmsg' => 'token 过期'
            ], $e->getStatusCode());

        } catch (TokenInvalidException $e) {

            return response()->json([
                'errcode' => 400003,
                'errmsg' => 'token 失效'
            ], $e->getStatusCode());

        } catch (JWTException $e) {

            return response()->json([
                'errcode' => 400002,
                'errmsg' => 'token 参数错误'
            ], $e->getStatusCode());

        }
        return $next($request);
    }


}

注册该中间件----编辑app/Http/Kernel.php

创建控制器处理所有的请求

php artisan make:controller  User\ApiController
<?php

namespace App\Http\Controllers\User;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Admin;
use Tymon\JWTAuth\Facades\JWTAuth;


class ApiController extends Controller
{
    /*注册*/
    public function register(Request $request)
    {
        $input = $request->all();
        $input['password'] = md5($input['password']);
        Admin::create($input);
        return response()->json(['result'=>true]);
    }

    /*登陆*/
    public function login(Request $request)
    {
        \Config::set('jwt.user' , "App\Models\Admin");
        \Config::set('auth.providers.users.model', \App\Models\Admin::class);
        $input = $request->all();
        $input['password'] = md5($input['password']);
        if($user=Admin::where($input)->first()){
            $token=JWTAuth::fromUser($user);
        }else{
            return response()->json(['result' => '账号或密码错误.']);
        }

        return response()->json(['result' => $token]);
    }

    /*获取用户信息*/
    public function get_user_details(Request $request)
    {
        $user = JWTAuth::toUser(JWTAuth::getToken());
        return response()->json(['result' => $user]);
    }

    public function quitLogin()
    {
        JWTAuth::invalidate(JWTAuth::getToken());
        return response()->json(['msg' =>'退出成功']);
    }
}

创建自己的用户模型 (使用框架的权限和用户表可以省去此步奏)

php artisan make:model  Models/Admin

编辑路由文件 routes\api.php

<?php

use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group(['middleware' => ['api','cors']], function () {
    Route::post('register', 'User\ApiController@register');     // 注册
    Route::post('login', 'User\ApiController@login');           // 登陆
    Route::group(['middleware' => 'jwt.auth'], function () {
        Route::get('get_user_details', 'User\APIController@get_user_details');  // 获取用户详情
        Route::get('quitLogin', 'User\APIController@quitLogin');  // 退出登录
    });
});

测试 使用(postman)

1.注册

2.登录 获取token

3.请求用户信息

如果token 错误

猜你喜欢

转载自blog.csdn.net/qq_36514588/article/details/82186617