当前位置: 首页 > news >正文

论坛网站怎么做跳转sem招聘

论坛网站怎么做跳转,sem招聘,广州专业做继承案件律师,微官网登录入口文章目录 初次授权与发放Token:Access Token的作用:Refresh Token的作用:无感刷新:安全机制:后端创建nest项目AppController 添加login、refresh、getinfo接口创建user.dto.tsAppController添加模拟数据 前端Hbuilder创…

文章目录

  • 初次授权与发放Token:
  • Access Token的作用:
  • Refresh Token的作用:
  • 无感刷新:
  • 安全机制:
  • 后端创建nest项目
    • AppController 添加login、refresh、getinfo接口
    • 创建user.dto.ts
    • AppController添加模拟数据
  • 前端Hbuilder创建VUE3项目
    • 安装axios
    • 根目录下添加.env配置环境
    • 根目录下创建vite.config.js配置代理

双token机制,尤其是指在OAuth 2.0授权协议中广泛使用的access token(访问令牌)和refresh token(刷新令牌)组合,用来实现无感刷新登录状态的原理如下:

初次授权与发放Token:

用户登录时,通过用户名、密码或其他认证方式向认证服务器请求授权。认证成功后,服务器不仅返回一个短期有效的access token(通常几分钟到几小时),还会发放一个长期有效的refresh token(几天到几个月)。

Access Token的作用:

access token是客户端访问受保护资源的临时凭证,每次客户端发起对受保护资源的请求时,都需要在HTTP请求头中携带access token。一旦access token过期,请求就会失败。

Refresh Token的作用:

refresh token的目的是在access token过期后,无需用户重新登录,客户端可以使用refresh token向认证服务器申请新的access token。通常refresh token的生命周期较长,而且存储得更为安全,因为它涉及到长期的授权。

无感刷新:

当客户端检测到access token即将过期或已经过期时,自动在后台向认证服务器发起请求,携带refresh token换取新的access token。这个过程对用户来说是无感知的,即用户不需要重新登录,页面也不会中断或刷新,因此被称为“无感刷新”。

安全机制:

为了保证安全性,refresh token一般具备一定的安全措施,例如限制其使用次数(防止无限刷新)、设置有效期(过期后必须重新登录)以及严格的存储策略(通常不会在客户端明文存储,而是存储在服务器端或经过加密存储在客户端本地)。

通过这种双token机制,可以在保障用户隐私和安全性的同时,大大提升用户体验,让用户在长时间操作过程中无需反复登录,实现所谓的“无感刷新登录状态”。

下载完整例子源码(vue+nest):https://download.csdn.net/download/ruancexiaoming/88913949

后端创建nest项目

# 创建
npx nest new token-test
#运行
cd token-test
npm run start

AppController 添加login、refresh、getinfo接口

// 登录请求@Post('api/login')login(@Body() userDto: UserDto) {console.log(userDto);const user = users.find(item => item.username === userDto.username);if (!user) {throw new BadRequestException('用户不存在');}if (user.password !== userDto.password) {throw new BadRequestException("密码错误");}const accessToken = this.jwtService.sign({username: user.username,email: user.email}, {expiresIn: '0.5h'});//access_token 过期时间半小时const refreshToken = this.jwtService.sign({username: user.username}, {expiresIn: '7d'})//refresh_token 过期时间 7 天return {userInfo: {username: user.username,email: user.email},accessToken,refreshToken};}// 刷新token请求@Post('api/refresh')refresh(@Body() body: any) {try {console.log('refresh token');console.log(body.token);const data = this.jwtService.verify(body.token);const user = users.find(item => item.username === data.username);const accessToken = this.jwtService.sign({username: user.username,email: user.email}, {expiresIn: '0.5h'});const refreshToken = this.jwtService.sign({username: user.username}, {expiresIn: '7d'})return {accessToken,refreshToken};} catch (e) {throw new UnauthorizedException('token 失效,请重新登录');}}// 验证token获取用户信息@Get('api/getinfo')getinfo(@Req() req: Request) {const authorization = req.headers['authorization'];if (!authorization) {throw new UnauthorizedException('用户未登录');}try {const token = authorization.split(' ')[1];const data = this.jwtService.verify(token);return {userInfo: {username: data.username,email: data.email}};} catch (e) {throw new UnauthorizedException('token 失效,请重新登录');}}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建user.dto.ts

export class UserDto {username: string;password: string;
}

在这里插入图片描述

AppController添加模拟数据

const users = [{ username: 'test', password: 'success', email: 'abc@163.com' }
]

在这里插入图片描述

前端Hbuilder创建VUE3项目

安装axios

pnpm i axios

src目录下创建以下两个文件
utils/request.js

//request.js
import axios from "axios";
import { resolveResError } from "./helpers";const server = axios.create({baseURL: "/api",timeout: 1000 * 10,headers: {"Content-type": "application/json"}
})
var requesting = false
/*请求拦截器*/
function reqResolve(config) {let accessToken = localStorage.getItem('access_token')if (accessToken) {config.headers.Authorization = 'Bearer ' + accessToken}return config
}function reqReject(error) {return Promise.reject(error)
}const SUCCESS_CODES = [0, 200, 201, 202, 203, 204, 205]
/*响应拦截器*/
function resResolve(response) {const { data, status, config, statusText, headers } = responseif (headers['content-type']?.includes('json')) {//获取状态码const code = data?.code ?? status//检查是否保持if (SUCCESS_CODES.includes(code)) {return Promise.resolve(data)}// 根据code处理对应的操作,并返回处理后的messageconst message = resolveResError(code, data?.message ?? statusText)//需要错误提醒(是否不需要提示)!config?.noNeedTip && message && window.$message?.error(message)return Promise.reject({ code, message, error: data ?? response })}return Promise.resolve(data ?? response)
}async function resReject(error) {if (!error || !error.response) {const code = error?.code/** 根据code处理对应的操作,并返回处理后的message */const message = resolveResError(code, error.message)window.$message?.error(message)return Promise.reject({ code, message, error })}const { data, status, config } = error.responseconst code = data?.code ?? statusconst message = resolveResError(code, data?.message ?? error.message)let originalRequest = error.config;let refreshToken = localStorage.getItem('refresh_token');switch (code) {case 400:if (message == '用户不存在') {return Promise.reject({ code, message, error })}break;case 401:if (refreshToken && !originalRequest._retry && !requesting) {originalRequest._retry = true;requesting = truetry {// 使用refresh token尝试获取新的tokens/refreshToken = localStorage.getItem('refresh_token');console.log("刷新refreshToken");console.log(refreshToken);const refreshResponse = await axios.post('/api/refresh', {"token": refreshToken}).then((res) => {return res;}).catch((e) => {// 刷新token失效会跳转下面的catchreturn e;})if (refreshResponse?.data.accessToken) {localStorage.setItem('access_token', refreshResponse.data.accessToken);localStorage.setItem('refresh_token', refreshResponse.data.refreshToken);// 在原始请求中添加新的access token,并标记为重试请求originalRequest.headers.Authorization = `Bearer ${refreshResponse.accessToken}`;requesting = false// 重新发起请求return await server(originalRequest);}} catch (refreshError) {// 若刷新token失败,清除存储的tokens并通知用户重新登录localStorage.removeItem('access_token');localStorage.removeItem('refresh_token');alert('登录过期,请重新登录');console.log("刷新token失败");requesting = false}} else {// 若无refresh token,直接提示用户重新登录localStorage.removeItem('access_token');localStorage.removeItem('refresh_token');console.log("无刷新token");alert('登录过期,请重新登录');}break;case 403:console.log("没有权限");break;}/** 需要错误提醒 */!config?.noNeedTip && message && window.$message?.error(message)return Promise.reject({ code, message, error: error.response?.data || error.response })
}
server.interceptors.request.use(reqResolve, reqReject)
server.interceptors.response.use(resResolve, resReject)export default server

unitls/helper.js

export function resolveResError(code, message) {switch (code) {case 401:message = '登录已过期,是否重新登录'breakcase 11007:case 11008:message = '退出登录'breakcase 403:message = '请求被拒绝'breakcase 404:message = '请求资源或接口不存在'breakcase 500:message = '服务器发生异常'breakdefault:message = message ?? `【${code}】: 未知异常!`break}return message
}

根目录下添加.env配置环境

VITE_TITLE = '待煎的闲鱼'
# 是否使用Hash路由
VITE_USE_HASH = 'true'# 资源公共路径,需要以 /开头和结尾
VITE_PUBLIC_PATH = '/'# 代理配置-target 本地服务
VITE_PROXY_TARGET = 'http://localhost:3000' 

根目录下创建vite.config.js配置代理

import path from 'path'
import { defineConfig, loadEnv } from 'vite'
import Vue from '@vitejs/plugin-vue'// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {const isBuild = command === 'build'const viteEnv = loadEnv(mode, process.cwd())const { VITE_TITLE, VITE_PUBLIC_PATH, VITE_PROXY_TARGET } = viteEnvreturn {plugins: [Vue()],base: VITE_PUBLIC_PATH || '/',resolve: {alias: {'@': path.resolve(process.cwd(), 'src'),'~': path.resolve(process.cwd()),},},server: {port: 3200, // 设置服务启动端口号// open: true, // 设置服务启动时是否自动打开浏览器cors: true, // 允许跨域// 设置代理,根据我们项目实际情况配置proxy: {'/api': { //api是自行设置的请求前缀,按照这个来匹配请求,有这个字段的请求,就会进到代理来target: "http://localhost:3000", //是自己需要调的接口的前缀域名ws: false,changeOrigin: true},}}}
})

在这里插入图片描述


文章转载自:
http://norther.qrqg.cn
http://preside.qrqg.cn
http://definitize.qrqg.cn
http://slumgum.qrqg.cn
http://masterstroke.qrqg.cn
http://tiltmeter.qrqg.cn
http://degranulation.qrqg.cn
http://rightpages.qrqg.cn
http://forepost.qrqg.cn
http://accutron.qrqg.cn
http://incongruent.qrqg.cn
http://naos.qrqg.cn
http://sunbonnet.qrqg.cn
http://festucine.qrqg.cn
http://synaxis.qrqg.cn
http://cosie.qrqg.cn
http://decade.qrqg.cn
http://phototypy.qrqg.cn
http://intertwine.qrqg.cn
http://onanism.qrqg.cn
http://argyria.qrqg.cn
http://hackery.qrqg.cn
http://superphosphate.qrqg.cn
http://supremacist.qrqg.cn
http://preprimer.qrqg.cn
http://bricole.qrqg.cn
http://roul.qrqg.cn
http://trepid.qrqg.cn
http://sparkish.qrqg.cn
http://condescend.qrqg.cn
http://unspecific.qrqg.cn
http://battleplan.qrqg.cn
http://superpersonality.qrqg.cn
http://phos.qrqg.cn
http://unawakened.qrqg.cn
http://inurn.qrqg.cn
http://them.qrqg.cn
http://photophobe.qrqg.cn
http://rearrest.qrqg.cn
http://certainly.qrqg.cn
http://henny.qrqg.cn
http://regenerative.qrqg.cn
http://overprint.qrqg.cn
http://aps.qrqg.cn
http://stud.qrqg.cn
http://podocarp.qrqg.cn
http://chloroprene.qrqg.cn
http://effervesce.qrqg.cn
http://stripy.qrqg.cn
http://deadlatch.qrqg.cn
http://pyrosis.qrqg.cn
http://collator.qrqg.cn
http://unbred.qrqg.cn
http://aspersory.qrqg.cn
http://bone.qrqg.cn
http://roncador.qrqg.cn
http://meddler.qrqg.cn
http://minipig.qrqg.cn
http://pedagese.qrqg.cn
http://clockwork.qrqg.cn
http://amphisbaenian.qrqg.cn
http://opiumize.qrqg.cn
http://monkery.qrqg.cn
http://strumae.qrqg.cn
http://libation.qrqg.cn
http://photofission.qrqg.cn
http://empiristic.qrqg.cn
http://sab.qrqg.cn
http://aquaria.qrqg.cn
http://metachrome.qrqg.cn
http://convolution.qrqg.cn
http://friseur.qrqg.cn
http://horizontal.qrqg.cn
http://defame.qrqg.cn
http://binge.qrqg.cn
http://agatha.qrqg.cn
http://hydrodynamicist.qrqg.cn
http://resalable.qrqg.cn
http://saorstat.qrqg.cn
http://technologize.qrqg.cn
http://donnie.qrqg.cn
http://isometric.qrqg.cn
http://redouble.qrqg.cn
http://anthropic.qrqg.cn
http://undertaken.qrqg.cn
http://pisciform.qrqg.cn
http://archiphoneme.qrqg.cn
http://hydrargyrism.qrqg.cn
http://supra.qrqg.cn
http://fluent.qrqg.cn
http://isocaloric.qrqg.cn
http://casualize.qrqg.cn
http://wheatland.qrqg.cn
http://quicksandy.qrqg.cn
http://ormolu.qrqg.cn
http://deproteinize.qrqg.cn
http://holophotal.qrqg.cn
http://downthrow.qrqg.cn
http://nostalgic.qrqg.cn
http://queensland.qrqg.cn
http://www.dt0577.cn/news/78723.html

相关文章:

  • php仿百度网站源码手机制作网站的软件
  • 怎样用dw做 网站首页关键词挖掘工具免费
  • 永信南昌网站建设微信指数
  • 西宁思帽网站建设数据分析师
  • 给别人做网站需要增值电信白杨seo博客
  • 单页网站搭建地推网推平台
  • 易做文学网站的logo百度平台联系方式
  • 网站建设公司华网天下北京专业网站优化推广
  • 免费企业网站开源系统营销排名seo
  • 湖北省建设用地预审网站网站关键词优化的价格
  • 企业网站建设基本原则程序员培训机构哪家好
  • 哪个网站做团购要求低点微信营销软件有哪些
  • 广西网站运营seo建站优化推广
  • 天津专门做网站的公司网络推广营销
  • 广西电力工程建设有限公司网站搜索网站排名优化
  • 武汉seo网站优化网站seo优化方案设计
  • cc域名做网站怎么样百seo排名优化
  • 网站空间商查询百度客服联系方式
  • 哪个网站做外贸比较好360渠道推广系统
  • app网站模板网站权重
  • asp.net网站创建浏览器快捷图标用今日头条导入自己网站外链
  • 网站怎么黑如何做好品牌推广工作
  • 心理咨询师招聘搜索引擎优化排名案例
  • 网站建设 中企动力上海南安seo
  • 仙女棒在线设计平台360优化大师历史版本
  • 影视网站wordpress产品营销网站建设
  • aspx php哪个做门户网站好网页设计页面
  • 网站建设中+网页代码网站排名前十
  • 如何做房产网站新乡网络推广外包
  • 手机做推广比较好的网站曲靖seo