Heim > Web-Frontend > uni-app > Uni-App-Applet Laravel+JWT-Autoritätsauthentifizierungsserie

Uni-App-Applet Laravel+JWT-Autoritätsauthentifizierungsserie

coldplay.xixi
Freigeben: 2020-11-27 17:15:55
nach vorne
12328 Leute haben es durchsucht

In der Spalte „Tutorial zur Uni-App-Entwicklung“ werden eine Reihe von Berechtigungsauthentifizierungsmethoden vorgestellt. Ich habe empfohlen:

Uni-APP-Entwicklungs-Tutorial Uni-App-Applet Laravel+JWT-Autoritätsauthentifizierungsserie

Umgebungsbeschreibung Uni-APP Laravel 5.7 + jwt -auth 1.0.0

Allgemeine Beschreibung der Autoritätsauthentifizierung

  1. Tabellenstruktur entwerfen
  2. Front-End-Anfrageklasse
  3. Das js-Paket im Zusammenhang mit der Autoritätsauthentifizierung enthält ein nicht bewusstes Aktualisierungstoken
  4. Die Laravel-Authentifizierungs-Middleware enthält ein nicht bewusstes Aktualisierungstoken
  5. Beziehen einer Mobiltelefonnummer zum Anmelden
  6. Painless-Refresh-Access_Token-Idee
  7. Wie ermittelt das Applet den Anmeldestatus?

Die Designtabellenstruktur

uni-app
laravel 5.7 + jwt-auth 1.0.0

权限认证整体说明

  1. 设计表结构
  2. 前端 request 类
  3. 有关权限认证的 js 封装 包含无感知刷新 token
  4. laravel auth 中间件 包含无感知刷新 token
  5. 获取手机号登陆
  6. 无痛刷新 access_token 思路
  7. 小程序如何判断登陆状态

设计表结构

和一般设计表没有什么区别,如果是多平台小程序,通过 account_id 关联联合表。

CREATE TABLE `users` (
  `u_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '账号id',
  `u_username` varchar(15) NOT NULL DEFAULT '' COMMENT '手机号隐藏 ',
  `u_nickname` varchar(15) NOT NULL COMMENT '分配用户名',
  `u_headimg` varchar(200) DEFAULT NULL COMMENT '头像',
  `u_province` varchar(50) DEFAULT NULL,
  `u_city` varchar(50) DEFAULT NULL,
  `u_platform` varchar(30) NOT NULL COMMENT '平台:小程序wx,bd等',
  `u_mobile` char(11) NOT NULL COMMENT '手机号必须授权',
  `u_openid` varchar(100) DEFAULT NULL COMMENT 'openid',
  `u_regtime` timestamp NULL DEFAULT NULL COMMENT '注册时间',
  `u_login_time` timestamp NULL DEFAULT NULL COMMENT '最后登陆时间',
  `u_status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '0禁用1正常',
  `account_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '平台联合id',
  PRIMARY KEY (`u_id`),
  KEY `platform` (`u_platform`,`u_mobile`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;
Nach dem Login kopieren

2. 前端 request 类

一个较不错的 request 类 luch-request
unterscheidet sich nicht von der allgemeinen Designtabelle ist ein plattformübergreifendes Applet, die gemeinsame Tabelle ist über account_id verknüpft. Uni-App-Applet Laravel+JWT-Autoritätsauthentifizierungsserie

import Request from './request';import jwt from '@/utils/auth/jwt.js'; // jwt 管理 见下文const http = new Request();const baseUrl = 'http://xxx'; // api 地址var platform = ''; // 登陆时需知道来自哪个平台的小程序用户// #ifdef MP-BAIDUplatform = 'MP-BAIDU';// #endif/* 设置全局配置 */http.setConfig((config) => { 
  config.baseUrl = baseUrl; //设置 api 地址
  config.header = {
    ...config.header  }
  return config})/* 请求之前拦截器 */http.interceptor.request((config, cancel) => {
    if (!platform) {cancel('缺少平台参数');}
    config.header = {
        ...config.header,
        platform:platform    } 
  if (config.custom.auth) {
      // 需要权限认证的路由 需携带自定义参数 {custom: {auth: true}}
    config.header.Authorization = jwt.getAccessToken();
  }
  return config})http.interceptor.response(async (response) => { /* 请求之后拦截器 */
    console.log(response);
    // 如果是需要权限认证的路由
    if(response.config.custom.auth){

            if(response.data.code == 4011){
                // 刷新 token
                jwt.setAccessToken(response.data.data.access_token);
                // 携带新 token 重新请求
                let repeatRes = await http.request(response.config);
                if ( repeatRes ) {
                    response = repeatRes;
                }
            }

    }
    return response}, (response) => { // 请求错误做点什么
    if(response.statusCode == 401){
        getApp().globalData.isLogin = false;
        uni.showToast({icon:'none',duration:2000,title: "请登录"})
    }else if(response.statusCode == 403){
        uni.showToast({
            title: "您没有权限进行此项操作,请联系客服。",
            icon: "none"
        });
    }
  return response})export {
  http}
Nach dem Login kopieren

2. Front-End-Anfrageklasse

Eine relativ gute Anfrageklasse luch-request unterstützt die dynamische Änderung von Konfigurationen und Interceptoren und ist im Uni-App-Plug-in-Markt zu finden .

request.js muss nicht geändert werden. Benutzerdefinierte Logik befindet sich in index.js.

index.js

import Vue from 'vue'import App from './App'import { http } from '@/utils/luch/index.js' //这里Vue.prototype.$http = http

Vue.config.productionTip = falseApp.mpType = 'app'const app = new Vue({
    ...App})app.$mount()
Nach dem Login kopieren

Global mount

// #ifndef H5const loginCode = provider => {
    return new Promise((resolve, reject) => {
        uni.login({
            provider: provider,
            success: function(loginRes) {
                if (loginRes && loginRes.code) { resolve(loginRes.code) } else { reject("获取code失败") }
            },
            fail:function(){ reject("获取code失败")}
        });
    })}// #endifexport {
    loginCode //登录获取code}
Nach dem Login kopieren

3. js-Paket im Zusammenhang mit der Autoritätsauthentifizierung

authorize.js

Aus Platzgründen wird der vollständige Code nicht veröffentlicht werden nicht gebraucht ankommen. Beispiel: uni.checkSession(): Da jwt zum Übernehmen des Anmeldestatus des Applets verwendet wird, wird diese Methode derzeit nicht verwendet.

const tokenKey = 'accessToken';//键值const userKey    = 'user'; // 用户信息// tokenconst getAccessToken = function(){
    let token='';
    try {token = 'Bearer '+ uni.getStorageSync(tokenKey);} catch (e) {}
    return token;}const setAccessToken = (access_token) => {
    try {uni.setStorageSync(tokenKey, access_token);return true;} catch (e) {return false;}}const clearAccessToken = function(){
    try {uni.removeStorageSync(tokenKey);} catch (e) {}}// userinfoconst setUser = (user)=>{
    try {uni.setStorageSync(userKey, user);return true;} catch (e) {return false;}}const getUser = function(){
    try {return uni.getStorageSync(userKey)} catch (e) {return false;}}const clearUser = function(){
    try {uni.removeStorageSync(userKey)} catch (e) {}}export default {
  getAccessToken,setAccessToken,clearAccessToken,getUser,setUser,clearUser}
Nach dem Login kopieren

jwt.js

ist speziell für die Verwaltung von access_token mit wenig Code konzipiert und integriert auch die Verwaltung von Benutzerinformationen.

import {loginCode} from '@/utils/auth/authorize.js';import jwt from '@/utils/auth/jwt.js';import {http} from '@/utils/luch/index.js';const login=function(detail){
    return new Promise((resolve, reject) => {
        loginCode().then(code=>{
            detail.code = code;
            return http.post('/v1/auth/login',detail);
        })
        .then(res=>{
            jwt.setAccessToken(res.data.data.access_token);
            jwt.setUser(res.data.data.user);
            getApp().globalData.isLogin = true;
            resolve(res.data.data.user);
        })
        .catch(err=>{
            reject('登陆失败')
        })
    })}export default {login}
Nach dem Login kopieren

auth.js

kümmert sich nur um die Anmeldung, warum in eine separate Datei legen, sonst nichts, weil es überall verwendet wird

<?phpnamespace  App\Http\Middleware;use App\Library\Y;use Closure;use Exception;use Tymon\JWTAuth\Exceptions\JWTException;use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;use Tymon\JWTAuth\Exceptions\TokenExpiredException;class ApiAuth extends BaseMiddleware{

    public function handle($request, Closure $next, $guard = &#39;api&#39;)
    {
        // 在排除名单中 比如登录
        if($request->is(...$this->except)){
            return $next($request);
        }

        try {
            $this->checkForToken($request);// 是否携带令牌
            if ( $this->auth->parseToken()->authenticate() ) {
                return $next($request); //验证通过
            }
        }catch(Exception $e){
            // 如果token 过期
            if ($e instanceof TokenExpiredException) {
                try{
                    // 尝试刷新 如果成功 返给前端 关于前端如何处理的 看前边 index.js
                    $token = $this->auth->refresh();
                    return Y::json(4011, $e->getMessage(),['access_token'=>$token]);
                }catch(JWTException $e){
                    // 达到刷新时间上限
                    return Y::json(401, $e->getMessage());
                }
            }else{
                // 其他各种 直接返回 401 状态码 不再细分
                return Y::json(401, $e->getMessage());
            }
        }
    }

    protected $except = [
        'v1/auth/login',
    ];}
Nach dem Login kopieren

4. Laravel-Authentifizierungs-Middleware

Ein bisschen Geschwätz hier JWT-Auth-Aspekt. 1. Wenn ein Token abläuft und der Token aktualisiert wird, wird der ursprüngliche Token in der „Blacklist“ aufgeführt und wird ungültig. Tatsächlich verwaltet jwt-auth auch eine Datei zum Speichern der Blacklist, und ungültige Token werden erst gelöscht, wenn das Aktualisierungszeitlimit erreicht ist. Beispielsweise beträgt die Ablaufzeit 10 Minuten und das Aktualisierungslimit einen Monat. Während dieses Zeitraums wird eine große Anzahl von Blacklists erstellt, was sich auf die Leistung auswirkt. Versuchen Sie daher, den Ablauf so weit wie möglich anzupassen Die Zeit beträgt 60 Minuten, das Aktualisierungslimit beträgt zwei Wochen, oder die Ablaufzeit beträgt eine Woche und das Aktualisierungslimit beträgt einen Monat lang. 2. Was die schmerzlose Aktualisierungslösung betrifft: Wenn das Token abläuft, stellt das von mir verwendete Frontend zwei Anforderungen, um die Aktualisierung abzuschließen, von denen der Benutzer nichts weiß. Es gibt eine Lösung im Internet, die eine automatische Aktualisierung und Anmeldung direkt anfordert, aber ich Ich habe es nicht benutzt, aber ich weiß nichts anderes. Ich habe jedoch verschiedene JWT-Ausnahmen zusammengestellt, und die Schüler können sie bei Bedarf anpassen. TokenExpiredException läuft ab, TokenInvalidException kann das Token nicht analysieren, UnauthorizedHttpException trägt das Token nicht, JWTException das Token läuft ab oder erreicht das Aktualisierungslimit oder ein interner JWT-Fehler.

<template>
    <view>
        <button>获取手机号</button>
        <button>获取用户数据</button>
        <button>清除用户数据</button>
    </view></template><script>
    import auth from &#39;@/utils/auth/auth.js&#39;;
    import jwt from &#39;@/utils/auth/jwt.js&#39;;
    var _self;
    export default{
        data() {return {}},
        onLoad(option) {},
        onShow(){},
        methods: {
            decryptPhoneNumber: function(e){
                // console.log(e.detail);
                if( e.detail.errMsg == "getPhoneNumber:ok" ){ //成功
                    auth.login(e.detail);
                }
            },
            me: function(){
                this.$http.get(&#39;/v1/auth/me&#39;,{custom: {auth: true}}).then(res=>{
                    console.log(res,&#39;success&#39;)
                }).catch(err=>{
                    console.log(err,&#39;error60&#39;)
                })
            },
            clear: function(){
                jwt.clearAccessToken();
                jwt.clearUser();
                uni.showToast({
                    icon: &#39;success&#39;,
                    title: &#39;清除成功&#39;,
                    duration:2000,
                });
            }
        },
        components: {}
    }</script><style></style>
Nach dem Login kopieren

Der Autor ist der Meinung, dass diese Art der Aktualisierung sehr schwierig zu verwalten ist. Es ist besser, sich nach Ablauf erneut anzumelden Im Allgemeinen ist keine hohe Sicherheit erforderlich. Bei der nächsten https-Anfrage ist es besser, ein einmaliges Token zu verwenden. Die Middleware benötigt hier nur auth()->check() , false bedeutet nicht angemeldet.

5. Rufen Sie die Mobiltelefonnummer ab, um sich anzumelden , die Methode, die ich verwende, ist, Nachdem das Backend festgestellt hat, dass das Token abgelaufen ist, versucht es automatisch, es zu aktualisieren. Wenn die Aktualisierung erfolgreich ist, wird ein neues Token zurückgegeben. Im Antwort-Interceptor erfasst das Front-End den vereinbarten Code der Back-End-Antwort, speichert das neue Token stellt dann eine zweite Anfrage. Am Ende wird es als eine normale Anfrage wahrgenommen.

Eine andere Denkweise besteht darin, dass sich das Backend nach einem erfolgreichen Aktualisierungsversuch automatisch für den aktuellen Benutzer anmeldet und das neue Token im Header zurückgibt. Das Frontend ist nur für die Speicherung verantwortlich.

7. 小程序如何判断登陆状态

其实思路也很简单,非前后端分离怎么做的,前后端分离就怎么做,原理一样。非前后端分离,在每次请求时都会读取 session ,那么前后端分离,更好一些,有些公开请求不走中间件,也就无需判断登陆态,只有在需要权限认证的页面,在页面初始化时发出一次请求走中间件,以此判断登陆状态。
定义全局登陆检查函数

import jwt from '@/utils/auth/jwt.js';Vue.prototype.checkLogin = function(){
    var TOKEN  = jwt.getAccessToken();
    return new Promise((resolve, reject) => {
        if(TOKEN){
            http.get('/v1/auth/check',{custom: {auth: true}}).then(res=>{
                // 通过中间件 一定是登陆态
                resolve(true);
            }).catch(err=>{
                resolve(false);
                console.log(err) // 这里是401 403 后端500错误或者网络不好
            })
        }else{
            resolve(false) //没有token 一定是未登陆
        }
    })}
Nach dem Login kopieren

笔者最终放弃上面的这种检查登录的方式,直接检验storage中有user和token即视为登录状态。以被动的验证代替主动去验证,就是说用户执行一个请求,返回401,那么就改变登录状态。以后再补充。

前端

<script>
    export default {
        data() {
            return {
                isLogin:null
            }
        },
        onLoad() {
            this.checkLogin().then(loginStatus=>{
                this.isLogin = loginStatus;
            });
        },
        methods: {
        },
        components: {}
    }</script>
Nach dem Login kopieren

                                                       

Das obige ist der detaillierte Inhalt vonUni-App-Applet Laravel+JWT-Autoritätsauthentifizierungsserie. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:learnku.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage