前端工作小结3-token问题

1.使用请求拦截器,拦截vue所有请求,增加token参数

      使用倒数计时,假如token有效期60分钟,会在59分钟的时候去重新拿着refresh_Token,去请求新的token.

     注意:如果一个账号允许多人登录使用,上述方法没有问题,但是如果一个账号只允许一人登录,一个地点登录,那上述方法就不那么全面,这时候可以采用使用响应拦截器,拦截状态码进行对应的异常处理,然后判断哪些是token失效,再进行对应的登出操作或者是重新获取token。

2.完整代码

 
  1. import axios from 'axios'

  2. import { getToken } from '@/utils/auth'

  3. import { getToken_refresh } from '@/api/users'

  4. import router from '../router/index';

  5. // 创建axios实例

  6. const service = axios.create({

  7. baseURL: 'http://122.152.250.75:10101', // api的base_url

  8. // baseURL: 'http://127.0.0.1:8081/auth',

  9. timeout: 10000 // 请求超时时间

  10. })

  11. /*是否有请求正在刷新token*/

  12. window.isRefreshing = false

  13. /*被挂起的请求数组*/

  14. let refreshSubscribers = []

  15. /*获取刷新token请求的token*/

  16. function getRefreshToken () {

  17. return localStorage.getItem("refresh_token")

  18. }

  19. /*push所有请求到数组中*/

  20. function subscribeTokenRefresh (cb) {

  21. refreshSubscribers.push(cb)

  22. }

  23. /*刷新请求(refreshSubscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据)*/

  24. function onRrefreshed (token) {

  25. refreshSubscribers.map(cb => cb(token))

  26. }

  27. // request 请求拦截器

  28. service.interceptors.request.use(config => {

  29. if (getToken()) {

  30. config.params['access_token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改

  31. /*判断token是否将要过期*/

  32. var istoken = isTokenExpired();

  33. if (istoken) {

  34. /*判断是否正在刷新*/

  35. if (!window.isRefreshing) {

  36. /*将刷新token的标志置为true*/

  37. window.isRefreshing = true

  38. /*发起刷新token的请求*/

  39. var params = {

  40. refresh_token: localStorage.getItem('refresh_Token'),

  41. };

  42. getToken_refresh(params).then((res) => {

  43. /*将标志置为false*/

  44. window.isRefreshing = false

  45. /*成功刷新token*/

  46. // config.headers.Authorization = res.data.data.token_type + ' ' + res.data.data.token

  47. /*更新auth*/

  48. if(res.data.code == 0){

  49. alert("登录超时,请重新登录");

  50. router.push({ path: '/login' })

  51. return

  52. }

  53. localStorage.setItem('Token',res.data.data.access_token);

  54. localStorage.setItem('refresh_Token',res.data.data.refresh_token);

  55. localStorage.setItem("expired_at",res.data.data.expired_at);

  56. config.params['access_token'] = getToken()

  57. /*执行数组里的函数,重新发起被挂起的请求*/

  58. onRrefreshed(res.data.data.access_token)

  59. /*执行onRefreshed函数后清空数组中保存的请求*/

  60. refreshSubscribers = []

  61. }).catch(err => {

  62. alert(err.response.data.message)

  63. /*清除本地保存的auth*/

  64. // localStorage.removeItem('auth')

  65. window.location.href = '#/login'

  66. })

  67. }

  68. /*把请求(token)=>{....}都push到一个数组中*/

  69. let retry = new Promise((resolve, reject) => {

  70. /*(token) => {...}这个函数就是回调函数*/

  71. subscribeTokenRefresh((token) => {

  72. // config.headers.Authorization = 'Bearer ' + token

  73. config.params['access_token'] = token

  74. /*将请求挂起*/

  75. resolve(config)

  76. })

  77. })

  78. return retry

  79. }

  80. }else{

  81. router.push({ path: '/login' })

  82. }

  83. return config

  84. }, error => {

  85. // Do something with request error

  86. console.log("11111"+error) // for debug

  87. Promise.reject(error)

  88. })

  89. // response 响应拦截器

  90. service.interceptors.response.use(

  91. response => {

  92. // console.log(response)

  93. if (response.status !== 200) {

  94. if(response.status === 500) { // 服务器断开

  95. this.$message({

  96. showClose: true,

  97. message: '服务器断开,请稍后重试。',

  98. type: 'error'

  99. });

  100. }

  101. return Promise.reject(new Error(response.message || 'Error'))

  102. } else {

  103. return response

  104. }

  105. },error => {

  106. // console.log("cesc"+error)

  107. if (error.response.status === 401) { // token失效 ,重新获取token

  108. var params = {

  109. refresh_token: localStorage.getItem('refresh_Token'),

  110. };

  111. getToken_refresh(params).then((res) => {

  112. /*更新auth*/

  113. if(res.data.code == 0){

  114. alert("登录超时,请重新登录");

  115. router.push({ path: '/login' })

  116. return

  117. }

  118. localStorage.setItem('Token',res.data.data.access_token);

  119. localStorage.setItem('refresh_Token',res.data.data.refresh_token);

  120. localStorage.setItem("expired_at",res.data.data.expired_at);

  121. }).catch(err => {

  122. alert(err.response.data.message)

  123. /*清除本地保存的auth*/

  124. // localStorage.removeItem('auth')

  125. window.location.href = '#/login'

  126. })

  127. }else if(error.response.status === 500) { // 服务器断开

  128. alert("服务器断开,请稍后重试。");

  129. }else if(error.response.status === 403){ //无auth授权,后台不允许访问

  130. alert("不允许访问,请与技术人员联系");

  131. }

  132. return response

  133. return Promise.reject(error)

  134. }

  135. )

  136. /*判断token是否过期*/

  137. function isTokenExpired() {

  138. let expiredTime = new Date().getTime() / 1000;

  139. /*从localStorage中取出token过期时间*/

  140. if(localStorage.getItem("expired_at") != undefined && localStorage.getItem("expired_at") != "undefined"){

  141. expiredTime = new Date(localStorage.getItem("expired_at")).getTime() / 1000

  142. }

  143. /*获取本地时间*/

  144. let nowTime = new Date().getTime() / 1000

  145. /*如果 < 10分钟,则说明即将过期*/

  146. var flag = (expiredTime - nowTime) < 10*60;

  147. // return (expiredTime - nowTime) < 10*60;

  148. return flag;

  149. }

  150. export default service

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值