Vue3+Vite がデュアル トークンを使用して無意味なリフレッシュを実現する方法
1. トークンログイン認証
jwt: JSON Web トークン。これは、要求された ID 情報と ID 権限を確認するために通常使用される認証プロトコルです。これは 3 つの部分で構成されます: ヘッダー、ヘイロード、署名
header: つまり、このトークンを説明する基本情報であるヘッダー情報 json format
{ "alg": "HS256", // 表示签名的算法,默认是 HMAC SHA256(写成 HS256) "type": "JWT" // 表示Token的类型,JWT 令牌统一写为JWT }
payload: ペイロードJSON オブジェクトでもあり、転送する必要がある実際のデータを保存するために使用されます。パスワードなどの機密情報を保存することはお勧めできません。
{ "iss": "a.com", // 签发人 "exp": "1d", // expiration time 过期时间 "sub": "test", // 主题 "aud": "", // 受众 "nbf": "", // Not Before 生效时间 "iat": "", // Issued At 签发时间 "jti": "", // JWT ID 编号 // 可以定义私有字段 "name": "", "admin": "" }
署名は、データの改ざんを防ぐための最初の 2 つの部分の署名です。キーを指定する必要があります。このキーはサーバーのみが知っており、漏洩することはありません。ヘッダーで指定された署名アルゴリズムを使用して、式に従って署名を生成します。
署名を計算したら、ヘッダー、ペイロード、署名の 3 つの部分を 1 つの文字列に結合し、各部分を で区切ります。これにより、トークンが生成されます
# 2. ダブル トークンとは- #accessToken
: データへのユーザー アクセス
#refreshToken - : 新しい accessToken を取得するために使用されます
二重トークン検証メカニズム。accessToken の有効期限は短く、refreshToken の有効期限は長くなります。 accessToken の有効期限が切れたら、refreshToken を使用して新しいトークンをリクエストします。
- リクエスト インターセプターでは、リクエスト ヘッダーに accessToken リクエスト データが含まれており、サーバーは accessToken の有効期限が切れているかどうかを確認します。トークンが有効な場合はデータのリクエストを続行し、トークンが無効な場合は無効化情報をクライアントに返します。
#クライアントは、サーバーから送信されたリクエスト情報を受信し、2 回カプセル化された axios レスポンス インターセプターに accessToken 無効化情報があるかどうかを判断しますが、レスポンス データは返されません。無効な情報がある場合は、refreshToken を持参して新しい accessToken を要求します。
サーバーは、refreshToken が有効かどうかを検証します。有効な場合はトークンが再生成され、新しいトークンとプロンプト情報がクライアントに返され、無効な場合は無効な情報がクライアントに返されます。
クライアント応答インターセプターは、応答情報に有効なリフレッシュトークンがあるか無効であるかを判断します。無効です。現在のログインからログアウトします。有効です。新しいトークンを再保存し、最後のリクエストのデータのリクエストを続行します。
注意事項
ショート トークンが無効です。サーバーはリクエストを拒否し、トークン無効化情報を返します。新しいショート トークンを再度リクエストする方法フロントエンドが要求したときに、非機密リフレッシュの効果を達成するためのデータ。
サーバー側のホワイトリストでは、ログインが成功する前にトークンが要求されていないため、サーバーが要求を傍受すると、ログインできなくなります。ログインにトークン検証が必要ないようにホワイトリストをカスタマイズします。
3. サーバー コード
1. koa2 サーバーの構築
koa スキャフォールディングをグローバルにインストール
npm install koa-generator -g
サーバーを直接作成 koa2 プロジェクトname
koa2 server
cd サーバー jwt をインストールするプロジェクトを入力します。
npm i jsonwebtoken
サーバー側で直接 koa-cors を使用できるようにするため、クロスドメイン
npm i koa-cors
アプリケーションを紹介します。 app.js の cors
const cors=require('koa-cors') ... app.use(cors())
2. ダブル トークン
New utils/token.js
const jwt=require('jsonwebtoken') const secret='2023F_Ycb/wp_sd' // 密钥 /* expiresIn:5 过期时间,时间单位是秒 也可以这么写 expiresIn:1d 代表一天 1h 代表一小时 */ // 本次是为了测试,所以设置时间 短token5秒 长token15秒 const accessTokenTime=5 const refreshTokenTime=15 // 生成accessToken const setAccessToken=(payload={})=>{ // payload 携带用户信息 return jwt.sign(payload,secret,{expireIn:accessTokenTime}) } //生成refreshToken const setRefreshToken=(payload={})=>{ return jwt.sign(payload,secret,{expireIn:refreshTokenTime}) } module.exports={ secret, setAccessToken, setRefreshToken }
3. ルーティング
スキャフォールディングを使用して直接作成されたプロジェクトは既に app.js に含まれています ルーティング ミドルウェアを使用して、router/index.js
const router = require('koa-router')() const jwt = require('jsonwebtoken') const { getAccesstoken, getRefreshtoken, secret }=require('../utils/token') /*登录接口*/ router.get('/login',()=>{ let code,msg,data=null code=2000 msg='登录成功,获取到token' data={ accessToken:getAccessToken(), refreshToken:getReferToken() } ctx.body={ code, msg, data } }) /*用于测试的获取数据接口*/ router.get('/getTestData',(ctx)=>{ let code,msg,data=null code=2000 msg='获取数据成功' ctx.body={ code, msg, data } }) /*验证长token是否有效,刷新短token 这里要注意,在刷新短token的时候回也返回新的长token,延续长token, 这样活跃用户在持续操作过程中不会被迫退出登录。长时间无操作的非活 跃用户长token过期重新登录 */ router.get('/refresh',(ctx)=>{ let code,msg,data=null //获取请求头中携带的长token let r_tk=ctx.request.headers['pass'] //解析token 参数 token 密钥 回调函数返回信息 jwt.verify(r_tk,secret,(error)=>{ if(error){ code=4006, msg='长token无效,请重新登录' } else{ code=2000, msg='长token有效,返回新的token', data={ accessToken:getAccessToken(), refreshToken:getReferToken() } } }) })
4 にインターフェイスを作成します。アプリケーション ミドルウェア
utils/auth.js
const { secret } = require('./token') const jwt = require('jsonwebtoken') /*白名单,登录、刷新短token不受限制,也就不用token验证*/ const whiteList=['/login','/refresh'] const isWhiteList=(url,whiteList)=>{ return whiteList.find(item => item === url) ? true : false } /*中间件 验证短token是否有效 */ const cuth = async (ctx,next)=>{ let code, msg, data = null let url = ctx.path if(isWhiteList(url,whiteList)){ // 执行下一步 return await next() } else { // 获取请求头携带的短token const a_tk=ctx.request.headers['authorization'] if(!a_tk){ code=4003 msg='accessToken无效,无权限' ctx.body={ code, msg, data } } else{ // 解析token await jwt.verify(a_tk,secret.(error)=>{ if(error)=>{ code=4003 msg='accessToken无效,无权限' ctx.body={ code, msg, datta } } else { // token有效 return await next() } }) } } } module.exports=auth
を導入します。 app.js のアプリケーション ミドルウェア
const auth=requier(./utils/auth) ··· app.use(auth)
実際、単純な二重トークン検証を行うだけであれば、静的リソースの解析などの多くのミドルウェアは必要ありません。ただし、時間と利便性を節約するために、koa2 足場を直接使用しました。
最終ディレクトリ構造:
4. フロントエンド コード1. Vue3 Vite フレームワーク
フロント-end は Vue3 を使用します Vite のフレームワークは個人の使用習慣に依存します。
npm init vite@latest client_side
axios をインストールします
npm i axios
2.使用する定数を定義します
config/constants.js
export const ACCESS_TOKEN = 'a_tk' // 短token字段 export const REFRESH_TOKEN = 'r_tk' // 短token字段 export const AUTH = 'Authorization' // header头部 携带短token export const PASS = 'pass' // header头部 携带长token
3.期限切れのリクエストを保存して呼び出します
キーポイント: Promise を使用して、期限切れのトークンを含むリクエストを配列に保存し、保留状態に保ちます。つまり、resolve() を呼び出さないでください。新しいトークンを取得したら、再度リクエストしてください。 utils/refresh.js
export {REFRESH_TOKEN,PASS} from '../config/constants.js' import { getRefreshToken, removeRefreshToken, setAccessToken, setRefreshToken} from '../config/storage' let subsequent=[] let flag=false // 设置开关,保证一次只能请求一次短token,防止客户多此操作,多次请求 /*把过期请求添加在数组中*/ export const addRequest = (request) => { subscribes.push(request) } /*调用过期请求*/ export const retryRequest = () => { console.log('重新请求上次中断的数据'); subscribes.forEach(request => request()) subscribes = [] } /*短token过期,携带token去重新请求token*/ export const refreshToken=()=>{ if(!flag){ flag = true; let r_tk = getRefershToken() // 获取长token if(r_tk){ server.get('/refresh',Object.assign({},{ headers:{[PASS]=r_tk} })).then((res)=>{ //长token失效,退出登录 if(res.code===4006){ flag = false removeRefershToken(REFRESH_TOKEN) } else if(res.code===2000){ // 存储新的token setAccessToken(res.data.accessToken) setRefreshToken(res.data.refreshToken) flag = false // 重新请求数据 retryRequest() } }) } } }
4. カプセル化 axios
utlis/server.js
import axios from "axios"; import * as storage from "../config/storage" import * as constants from '../config/constants' import { addRequest, refreshToken } from "./refresh"; const server = axios.create({ baseURL: 'http://localhost:3004', // 你的服务器 timeout: 1000 * 10, headers: { "Content-type": "application/json" } }) /*请求拦截器*/ server.interceptors.request.use(config => { // 获取短token,携带到请求头,服务端校验 let aToken = storage.getAccessToken(constants.ACCESS_TOKEN) config.headers[constants.AUTH] = aToken return config }) /*响应拦截器*/ server.interceptors.response.use( async response => { // 获取到配置和后端响应的数据 let { config, data } = response console.log('响应提示信息:', data.msg); return new Promise((resolve, reject) => { // 短token失效 if (data.code === 4003) { // 移除失效的短token storage.removeAccessToken(constants.ACCESS_TOKEN) // 把过期请求存储起来,用于请求到新的短token,再次请求,达到无感刷新 addRequest(() => resolve(server(config))) // 携带长token去请求新的token refreshToken() } else { // 有效返回相应的数据 resolve(data) } }) }, error => { return Promise.reject(error) } )
5. カプセル化の再利用
import * as constants from "./constants" // 存储短token export const setAccessToken = (token) => localStorage.setItem(constanst.ACCESS_TOKEN, token) // 存储长token export const setRefershToken = (token) => localStorage.setItem(constants.REFRESH_TOKEN, token) // 获取短token export const getAccessToken = () => localStorage.getItem(constants.ACCESS_TOKEN) // 获取长token export const getRefershToken = () => localStorage.getItem(constants.REFRESH_TOKEN) // 删除短token export const removeAccessToken = () => localStorage.removeItem(constants.ACCESS_TOKEN) // 删除长token export const removeRefershToken = () => localStorage.removeItem(constants.REFRESH_TOKEN)
6. インターフェイスのカプセル化
apis/index.js
import server from "../utils/server"; /*登录*/ export const login = () => { return server({ url: '/login', method: 'get' }) } /*请求数据*/ export const getData = () => { return server({ url: '/getList', method: 'get' }) }
プロジェクトの実行
最後に、プロジェクトを実行し、バックエンドによって設定された短いトークン5を確認します。 、トークンの長さは 10 秒です。ログインリクエストがトークンに到達すると、正常にリクエストデータをリクエストできるようになりますが、5秒後に再度リクエストを行うと、ショートトークンは無効になりますが、このときロングトークンは有効になります。 、更新インターフェイスは 1 回だけ呼び出されます。ロングトークンの有効期限が切れたら、再度ログインする必要があります。以上がVue3+Vite がデュアル トークンを使用して無意味なリフレッシュを実現する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Vue3+TS+Vite 開発スキル: SEO 最適化の実行方法 SEO (SearchEngineOptimization) とは、Web サイトの構造、コンテンツ、キーワードを最適化して検索エンジンで上位にランク付けし、それによって Web サイトのトラフィックと露出を増やすことを指します。 Vue3+TS+Viteなどの最新のフロントエンド技術の開発において、SEOをいかに最適化するかは非常に重要な問題です。この記事では、Vue3+TS+Vite の開発テクニックとそのための方法をいくつか紹介します。

ページの部分的な更新を実現するには、ローカル コンポーネント (dom) の再レンダリングを実装するだけで済みます。 Vue でこの効果を実現する最も簡単な方法は、v-if ディレクティブを使用することです。 Vue2 では、v-if 命令を使用してローカル dom を再レンダリングすることに加えて、新しい空のコンポーネントを作成することもできます。ローカル ページを更新する必要がある場合は、この空のコンポーネント ページにジャンプしてから、再びジャンプします。 beforeRouteEnter ガードを空白のコンポーネントに配置します。元のページ。以下の図に示すように、Vue3.X の更新ボタンをクリックして赤枠内の DOM を再読み込みし、対応する読み込みステータスを表示する方法を示します。 Vue3.X の scriptsetup 構文のコンポーネントのガードには o しかないので、

Vue3+TS+Vite 開発スキル: クロスドメイン リクエストとネットワーク リクエストを最適化する方法 はじめに: フロントエンド開発では、ネットワーク リクエストは非常に一般的な操作です。ネットワーク リクエストを最適化してページの読み込み速度とユーザー エクスペリエンスを向上させる方法は、開発者が考慮する必要がある問題の 1 つです。同時に、異なるドメイン名にリクエストを送信する必要がある一部のシナリオでは、クロスドメインの問題を解決する必要があります。この記事では、Vue3+TS+Vite 開発環境でクロスドメイン リクエストを行う方法とネットワーク リクエストの最適化テクニックを紹介します。 1. クロスドメインリクエストソリューション

Vue3+TS+Vite 開発スキル: フロントエンドのセキュリティ保護を実行する方法 フロントエンド テクノロジの継続的な開発に伴い、ますます多くの企業や個人がフロントエンド開発に Vue3+TS+Vite を使用し始めています。しかし、それに伴うセキュリティリスクも人々の注目を集めています。この記事では、いくつかの一般的なフロントエンド セキュリティの問題について説明し、Vue3+TS+Vite の開発プロセス中にフロントエンド セキュリティを保護する方法に関するいくつかのヒントを共有します。入力の検証 ユーザー入力は、多くの場合、フロントエンドのセキュリティ脆弱性の主な原因の 1 つです。存在する

無効なログイン トークンの解決策には、トークンの有効期限が切れているかどうかの確認、トークンが正しいかどうかの確認、トークンが改ざんされているかどうかの確認、トークンがユーザーと一致するかどうかの確認、キャッシュまたは Cookie のクリア、ネットワーク接続とサーバーのステータスの確認が含まれます。 、再度ログインするか、新しいトークンをリクエストしてください。テクニカル サポートや開発者などにお問い合わせください。詳細な紹介: 1. トークンの有効期限が切れていないか確認する 通常、ログイントークンには有効期限が設定されており、有効期限を過ぎると無効となります。

vue3+vite:src は、イメージとエラー レポートと解決策を動的にインポートするために require を使用します。vue3+vite は複数のイメージを動的にインポートします。vue3。TypeScript 開発を使用している場合、イメージを導入するために require のエラー メッセージが表示されます。requireisnotdefined は使用できません。 vue2 のような imgUrl:require(' .../assets/test.png') は、typescript が require をサポートしていないため、インポートされます。そのため、import が使用されます。解決方法は次のとおりです: awaitimport を使用します

無効なログイン トークンの問題は、ネットワーク接続の確認、トークンの有効期間の確認、キャッシュと Cookie のクリア、ログイン ステータスの確認、アプリケーション開発者への連絡、アカウントのセキュリティの強化によって解決できます。詳細な導入: 1. ネットワーク接続を確認し、ネットワークに再接続するか、ネットワーク環境を変更します。 2. トークンの有効期間を確認し、新しいトークンを取得するか、アプリケーションの開発者に問い合わせます。 3. キャッシュと Cookie をクリアし、ブラウザをクリアします。キャッシュと Cookie を削除してから、アプリケーションに再度ログインします; 4. ログイン状態を確認します。

Vue3+TS+Vite 開発のヒント: データを暗号化して保存する方法 インターネット技術の急速な発展に伴い、データ セキュリティとプライバシー保護がますます重要になっています。 Vue3+TS+Vite 開発環境では、データをどのように暗号化して保存するかが、すべての開発者が直面する必要がある問題です。この記事では、開発者がアプリケーションのセキュリティとユーザー エクスペリエンスを向上させるのに役立つ、一般的なデータ暗号化とストレージのテクニックをいくつか紹介します。 1. データ暗号化 フロントエンド データ暗号化 フロントエンド暗号化は、データ セキュリティを保護するための重要な部分です。よく使われる
