uni-app 개발 튜토리얼 칼럼에서는 일련의 권한 인증 방법을 소개합니다. 내가 추천하는 것:
Uni-APP 개발 튜토리얼 환경 설명 Uni-APP
Laravel 5.7
+ jwt -auth 1.0.0
권한 인증에 대한 전반적인 설명
- 디자인 테이블 구조
- 프런트엔드 요청 클래스
- js 패키지 권한 인증과 관련된 비인식 새로고침 토큰이 포함되어 있습니다.
- laravel 인증 미들웨어에 비인식 새로고침 토큰이 포함되어 있습니다.
- 로그인을 위한 휴대폰 번호 가져오기
- 손쉬운 새로고침 access_token 아이디어
- 미니 프로그램은 로그인 상태를 어떻게 결정하나요?
uni-app
laravel 5.7
+ jwt-auth 1.0.0
权限认证整体说明
- 设计表结构
- 前端 request 类
- 有关权限认证的 js 封装 包含无感知刷新 token
- laravel auth 中间件 包含无感知刷新 token
- 获取手机号登陆
- 无痛刷新 access_token 思路
- 小程序如何判断登陆状态
设计表结构
和一般设计表没有什么区别,如果是多平台小程序,通过 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;
2. 前端 request 类
一个较不错的 request 类 luch-request
디자인 테이블 구조
는 일반 디자인 테이블과 다르지 않습니다. 이는 다중 플랫폼 미니 프로그램이며 account_id를 통해 공동 테이블을 연결합니다.
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}
2. 프론트엔드 요청 클래스
비교적 좋은 요청 클래스luch-request
는 동적으로 수정되는 구성과 인터셉터를 지원하며 유니앱 플러그인 마켓에서 찾을 수 있습니다. . request.js는 변경할 필요가 없습니다. 사용자 정의 논리는 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()
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}
3.js 권한 인증 관련 패키지
authorize.js
공간상의 이유로 전체 코드는 게시되지 않습니다. 도착하는 데 사용되지 않습니다. 예를 들어, uni.checkSession()은 jwt가 애플릿의 로그인 상태를 인계받는 데 사용되므로 이 메소드는 현재 사용되지 않습니다.
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}
jwt.js
는 별다른 코드 없이 access_token을 관리할 수 있도록 특별히 설계되었으며 사용자 정보 관리 기능도 담았습니다. 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}
auth.js
로그인만 처리하는데 왜 별도의 파일에 넣지 않고 모든 곳에서 사용되기 때문입니다<?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 = 'api') { // 在排除名单中 比如登录 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', ];}
4 laravel auth middleware
약간. 여기에서 jwt-auth 측면에 대해 이야기해 보세요. 1. 토큰이 만료되고 토큰이 새로 고쳐지면 원래 토큰이 "블랙리스트"에 나열되고 무효화됩니다. 실제로 jwt-auth는 블랙리스트를 저장하는 파일도 유지관리하며 유효하지 않은 토큰은 새로 고침 시간 제한에 도달한 경우에만 삭제됩니다. 예를 들어 만료 시간은 10분이고 새로 고침 제한은 1개월입니다. 이 기간 동안 블랙리스트가 대량으로 생성되어 성능에 영향을 미치므로 만료 시간 등을 최대한 조정해 보세요. 시간은 60분, 새로 고침 제한은 2주 또는 만료 시간은 1주일이고 새로 고침 제한은 한 달 동안 문제 없음입니다. 2. 무통 새로 고침 솔루션에 관해서는 토큰이 만료되면 제가 사용하는 프런트 엔드에서 새로 고침을 완료하기 위해 두 가지 요청을 하는데, 사용자는 이를 인식하지 못하고 인터넷에 직접 자동 새로 고침 및 로그인을 요청하는 솔루션이 있습니다. 그것을 사용하지 않았습니다. 이유는 다른 것을 이해할 수 없습니다. 그러나 나는 다양한 jwt 예외를 컴파일했으며 학생들은 필요한 경우 이를 사용자 정의할 수 있습니다. TokenExpiredException이 만료되고 TokenInvalidException이 토큰을 구문 분석할 수 없으며 UnauthorizedHttpException이 토큰을 전달하지 않습니다. JWTException 토큰이 만료되거나 새로 고침 제한에 도달하거나 jwt 내부 오류가 발생합니다.
<template> <view> <button>获取手机号</button> <button>获取用户数据</button> <button>清除用户数据</button> </view></template><script> import auth from '@/utils/auth/auth.js'; import jwt from '@/utils/auth/jwt.js'; 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('/v1/auth/me',{custom: {auth: true}}).then(res=>{ console.log(res,'success') }).catch(err=>{ console.log(err,'error60') }) }, clear: function(){ jwt.clearAccessToken(); jwt.clearUser(); uni.showToast({ icon: 'success', title: '清除成功', duration:2000, }); } }, components: {} }</script><style></style>
저자는 이런 새로고침은 유지관리가 매우 어렵다고 생각합니다. 일회용 토큰을 직접 사용하는 것이 더 좋으며 만료 후 다시 로그인하는 것이 좋습니다. 일반적으로 높은 보안이 필요하지 않습니다. 다음 번 https 요청 시 일회용 토큰을 사용하는 것이 좋습니다. 여기서 미들웨어는 auth()->check()만 필요하며 true는 로그인 상태를 의미합니다. , false는 로그인되지 않았음을 의미합니다.
5. 로그인할 휴대폰 번호 받기// 登陆
public function login(Request $request)
{
$platform = $request->header('platform');
if(!$platform || !in_array($platform,User::$platforms)){
return Y::json(1001, '不支持的平台类型');
}
$post = $request->only(['encryptedData', 'iv', 'code']);
$validator = Validator::make($post, [
'encryptedData' => 'required',
'iv' => 'required',
'code' => 'required'
]);
if ($validator->fails()) {return Y::json(1002,'非法请求');}
switch ($platform) {
case 'MP-BAIDU':
$decryption = (new BdDataDecrypt())->decrypt($post['encryptedData'],$post['iv'],$post['code']);
break;
default:
$decryption = false;
break;
}
// var_dump($decryption);
if($decryption !== false){
$user = User::where('u_platform',$platform)->where('u_mobile',$decryption['mobile'])->first();
if($user){
$user->u_login_time = date('Y-m-d H:i:s',time());
$user->save();
}else{
$user = User::create([
'u_username'=> substr_replace($decryption['mobile'],'******',3,6),
'u_nickname'=> User::crateNickName(),
'u_platform'=> $platform,
'u_mobile' => $decryption['mobile'],
'u_openid' => $decryption['openid'],
'u_regtime' => date('Y-m-d H:i:s',time())
]);
}
$token = auth()->login($user);
return Y::json(
array_merge(
$this->respondWithToken($token),
['user'=>['nickName'=>$user->u_nickname]]
)
);
}
return Y::json(1003,'登录失败');
}
// 返回 token
protected function respondWithToken($token)
{
return ['access_token' => $token];
}
Backend
<?phpnamespace App\Library;use App\Library\Y;class BdDataDecrypt{ private $_appid; private $_app_key; private $_secret; private $_session_key; public function __construct() { $this->_appid = env('BD_APPID'); $this->_app_key = env('BAIDU_KEY'); $this->_secret = env('BD_SECRET'); } public function decrypt($encryptedData, $iv, $code){ $res = $this->getSessionKey($code); if($res === false){return false;} $data['openid'] = $res['openid']; $res = $this->handle($encryptedData,$iv,$this->_app_key,$res['session_key']); if($res === false){return false;} $res = json_decode($res,true); $data['mobile'] = $res['mobile']; return $data; } public function getSessionKey($code) { $params['code'] = $code; $params['client_id'] = $this->_app_key; $params['sk'] = $this->_secret; $res = Y::curl("https://spapi.baidu.com/oauth/jscode2sessionkey",$params,0,1); // var_dump($res); /** * 错误返回 * array(3) { ["errno"]=> int(1104) ["error"]=> string(33) "invalid code , expired or revoked" ["error_description"]=> string(33) "invalid code , expired or revoked" } 成功返回: array(2) { ["openid"]=> string(26) "z45QjEfvkUJFwYlVcpjwST5G8w" ["session_key"]=> string(32) "51b9297ababbcf43c1a099256bf82d75" } */ if( isset($res['error']) ){ return false; } return $res; } /** * 官方 demo * return string(24) "{"mobile":"18288881111"}" or false */ private function handle($ciphertext, $iv, $app_key, $session_key) { $session_key = base64_decode($session_key); $iv = base64_decode($iv); $ciphertext = base64_decode($ciphertext); $plaintext = false; if (function_exists("openssl_decrypt")) { $plaintext = openssl_decrypt($ciphertext, "AES-192-CBC", $session_key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); } else { $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, null, MCRYPT_MODE_CBC, null); mcrypt_generic_init($td, $session_key, $iv); $plaintext = mdecrypt_generic($td, $ciphertext); mcrypt_generic_deinit($td); mcrypt_module_close($td); } if ($plaintext == false) { return false; } // trim pkcs#7 padding $pad = ord(substr($plaintext, -1)); $pad = ($pad 32) ? 0 : $pad; $plaintext = substr($plaintext, 0, strlen($plaintext) - $pad); $plaintext = substr($plaintext, 16); $unpack = unpack("Nlen/", substr($plaintext, 0, 4)); $content = substr($plaintext, 4, $unpack['len']); $app_key_decode = substr($plaintext, $unpack['len'] + 4); return $app_key == $app_key_decode ? $content : false; }}🎜🎜휴대폰 번호 복호화🎜🎜
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 一定是未登陆 } })}🎜🎜🎜6. 우선 제가 사용하는 방법은. is, backend 토큰이 만료되었다고 판단한 후 자동으로 새로 고침을 시도합니다. 새로 고침에 성공하면 새 토큰이 반환됩니다. 응답 인터셉터에서 프런트 엔드는 백엔드 응답의 합의된 코드를 캡처하고 새 토큰을 저장합니다. , 그리고 두 번째 요청을 하면 결국 1번으로 인식됩니다. 🎜 또 다른 사고 방식은 백엔드가 성공적으로 새로 고침을 시도한 후 자동으로 현재 사용자에 대해 로그인하고 헤더에 새 토큰을 반환한다는 것입니다. 🎜
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 一定是未登陆 } })}
笔者最终放弃上面的这种检查登录的方式,直接检验storage中有user和token即视为登录状态。以被动的验证代替主动去验证,就是说用户执行一个请求,返回401,那么就改变登录状态。以后再补充。
前端
<script> export default { data() { return { isLogin:null } }, onLoad() { this.checkLogin().then(loginStatus=>{ this.isLogin = loginStatus; }); }, methods: { }, components: {} }</script>
위 내용은 uni-app 애플릿 Laravel+jwt 권한 인증 시리즈의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

随着移动互联网技术和智能手机的普及,微信成为了人们生活中不可或缺的一个应用。而微信小程序则让人们可以在不需要下载安装应用的情况下,直接使用小程序来解决一些简单的需求。本文将介绍如何使用Python来开发微信小程序。一、准备工作在使用Python开发微信小程序之前,需要安装相关的Python库。这里推荐使用wxpy和itchat这两个库。wxpy是一个微信机器

小程序能用react,其使用方法:1、基于“react-reconciler”实现一个渲染器,生成一个DSL;2、创建一个小程序组件,去解析和渲染DSL;3、安装npm,并执行开发者工具中的构建npm;4、在自己的页面中引入包,再利用api即可完成开发。

VSCode中如何开发uni-app?下面本篇文章给大家分享一下VSCode中开发uni-app的教程,这可能是最好、最详细的教程了。快来看看!

如何利用uniapp开发一个贪吃蛇小游戏?下面本篇文章就手把手带大家在uniapp中实现贪吃蛇小游戏,希望对大家有所帮助!

实现思路x01服务端的建立首先,在服务端,使用socket进行消息的接受,每接受一个socket的请求,就开启一个新的线程来管理消息的分发与接受,同时,又存在一个handler来管理所有的线程,从而实现对聊天室的各种功能的处理x02客户端的建立客户端的建立就要比服务端简单多了,客户端的作用只是对消息的发送以及接受,以及按照特定的规则去输入特定的字符从而实现不同的功能的使用,因此,在客户端这里,只需要去使用两个线程,一个是专门用于接受消息,一个是专门用于发送消息的至于为什么不用一个呢,那是因为,只

uni-app接口,全局方法封装1.在根目录创建一个api文件,在api文件夹中创建api.js,baseUrl.js和http.js文件2.baseUrl.js文件代码exportdefault"https://XXXX.test03.qcw800.com/api/"3.http.js文件代码exportfunctionhttps(opts,data){lethttpDefaultOpts={url:opts.url,data:data,method:opts.method

本篇文章手把手带大家开发一个uni-app日历插件,介绍下一款日历插件是如何从开发到发布的,希望对大家有所帮助!


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

Dreamweaver Mac版
시각적 웹 개발 도구
