首先安装

composer require tymon/jwt-auth

默认安装后我的版本是2.1

    "require": {
        "php": "^8.2",
        ....
        "tymon/jwt-auth": "^2.1"
    },

发布包配置文件

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

生成密钥

php artisan jwt:secret

env 中会生成这段代码

JWT_SECRET=fW87rUsPjEy0UoE0J9CYbk44mBskdyPQrLehLDVRL3pUA4nq4umf8aoaoC6ugy55
AUTH_GUARD = api
AUTH_PASSWORD_BROKER = users

开始

首先更新user 模型

<?php

namespace App\Models;

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


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

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }


    // Rest omitted for brevity

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }

    
}

在 config/auth.php 文件中修改配置

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

在API路由中添加认证

Route::post('/auth/login', [App\Http\Controllers\Apis\AuthController::class,'login'])->name('login');


Route::group(['middleware' => 'auth:api'], function()
{
	Route::post('/auth/logout', [App\Http\Controllers\Apis\AuthController::class,'logout']);
	Route::post('/auth/refresh', [App\Http\Controllers\Apis\AuthController::class,'refresh']);
	Route::any('/auth/me', [App\Http\Controllers\Apis\AuthController::class,'me']);
});

创建AuthController.php

<?php
namespace App\Http\Controllers\Apis;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
use Auth;

class AuthController extends Controller
{

    public function __construct()
    {
        // $this->middleware('auth:api', ['except' => ['login']]);
    }

	public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');
        if ($token = $this->guard()->attempt($credentials)) {
            return $this->respondWithToken($token);
        }

        return response()->json(['error' => 'Unauthorized'], 401);
    }

    /**
     * Get the authenticated User
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json($this->guard()->user());
    }

    /**
     * Log the user out (Invalidate the token)
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        $this->guard()->logout();

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

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken($this->guard()->refresh());
    }

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

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\Guard
     */
    public function guard()
    {
        return Auth::guard();
    }

}

Login 页面

<style scoped>
    .login-box{
        width: 100%;
        padding-top: 100px;
    }
    .Loginform{
        width: 50%;
        margin: auto;
    }
</style>

<template>
    <div class="login-box">
        <h1 style="text-align: center;">喵~登录</h1>
        <el-form class="Loginform" :model="form" label-width="auto" style="max-width: 600px">
          <el-form-item label="邮箱">
            <el-input v-model="form.email" />
          </el-form-item>
          <el-form-item label="密码">
            <el-input type="password" v-model="form.password" ></el-input>
          </el-form-item>

            <el-form-item style="text-align: -webkit-center">
              <div style="width: 100%; text-align: center;">
                <el-button class="submit-btn" type="primary" @click="submitForm" style="justify-content: center;">登录</el-button>
              </div>
            </el-form-item>

        </el-form>
    </div>
</template>
      
<script lang="ts" setup>
import { ref,computed,onMounted } from 'vue';
import { Login } from '../apis/api';
import { useAuthStore } from '@/stores/auth';
import router from '../router'

// import { AuthToken } from '../interfaces/Auth'
  const form = ref({
    email: '',
    password: ''
  })


  const submitForm = () => {
    let Loginform = {"email":form.value.email,"password":form.value.password};
    Login(Loginform).then(function(res:any){
      if(res.access_token && res.expires_in && res.token_type=='bearer'){
        const authStore = useAuthStore();
        authStore.login(true,res.access_token)
        router.push('/admin/home');
      }
    })
  };

  onMounted(() => {
    // GetCsrfToken().then(function(res:any){
    //   form.value.csrfToken = res.csrf_token
    // })
  })





</script>

api.ts

import {post,get} from './https'

export const Login = (params:any) => post('/auth/login',params)

原理是,当用户登录客户端之后,后台会返回一段字符串给客户端,客户端之后的每一步操作都会通过字符串访问后台,判断其字符串是否已经登录,所以需要在客户端的路由中编写监听器,不过这是后话!

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部