Explorar el Código

OAuth自动刷新续签Token

RuoYi hace 5 años
padre
commit
43bc0ca39b

+ 11 - 0
ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/ValidateCodeFilter.java

@@ -31,6 +31,10 @@ public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
31 31
     private static final String CODE = "code";
32 32
 
33 33
     private static final String UUID = "uuid";
34
+    
35
+    private static final String GRANT_TYPE = "grant_type";
36
+    
37
+    private static final String REFRESH_TOKEN = "refresh_token";
34 38
 
35 39
     @Override
36 40
     public GatewayFilter apply(Object config)
@@ -43,6 +47,13 @@ public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
43 47
             {
44 48
                 return chain.filter(exchange);
45 49
             }
50
+            
51
+            // 刷新token请求,不处理
52
+            String grantType = request.getQueryParams().getFirst(GRANT_TYPE);
53
+            if (StringUtils.containsIgnoreCase(request.getURI().getPath(), AUTH_URL) && StringUtils.containsIgnoreCase(grantType, REFRESH_TOKEN))
54
+            {
55
+                return chain.filter(exchange);
56
+            }
46 57
 
47 58
             // 消息头存在内容,且不存在验证码参数,不处理
48 59
             String header = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);

+ 11 - 1
ruoyi-ui/src/api/login.js

@@ -2,11 +2,11 @@ import request from '@/utils/request'
2 2
 
3 3
 const client_id = 'web'
4 4
 const client_secret = '123456'
5
-const grant_type = 'password'
6 5
 const scope = 'server'
7 6
 
8 7
 // 登录方法
9 8
 export function login(username, password, code, uuid) {
9
+  const grant_type = 'password'
10 10
   return request({
11 11
     url: '/auth/oauth/token',
12 12
     method: 'post',
@@ -14,6 +14,16 @@ export function login(username, password, code, uuid) {
14 14
   })
15 15
 }
16 16
 
17
+// 刷新方法
18
+export function refreshToken(refresh_token) {
19
+  const grant_type = 'refresh_token'
20
+  return request({
21
+    url: '/auth/oauth/token',
22
+    method: 'post',
23
+    params: { client_id, client_secret, grant_type, scope, refresh_token }
24
+  })
25
+}
26
+
17 27
 // 获取用户详细信息
18 28
 export function getInfo() {
19 29
   return request({

+ 30 - 2
ruoyi-ui/src/store/modules/user.js

@@ -1,9 +1,10 @@
1
-import { login, logout, getInfo } from '@/api/login'
2
-import { getToken, setToken, removeToken } from '@/utils/auth'
1
+import { login, logout, getInfo, refreshToken } from '@/api/login'
2
+import { getToken, getRefreshToken, setToken, setRefreshToken, setExpiresIn, removeToken } from '@/utils/auth'
3 3
 
4 4
 const user = {
5 5
   state: {
6 6
     token: getToken(),
7
+    refresh_token: getRefreshToken(),
7 8
     name: '',
8 9
     avatar: '',
9 10
     roles: [],
@@ -14,6 +15,12 @@ const user = {
14 15
     SET_TOKEN: (state, token) => {
15 16
       state.token = token
16 17
     },
18
+    SET_EXPIRES_IN: (state, time) => {
19
+      state.expires_in = time
20
+    },
21
+    SET_REFRESH_TOKEN: (state, token) => {
22
+      state.refresh_token = token
23
+    },
17 24
     SET_NAME: (state, name) => {
18 25
       state.name = name
19 26
     },
@@ -39,6 +46,10 @@ const user = {
39 46
         login(username, password, code, uuid).then(res => {
40 47
           setToken(res.access_token)
41 48
           commit('SET_TOKEN', res.access_token)
49
+          setRefreshToken(res.refresh_token)
50
+          commit('SET_REFRESH_TOKEN', res.refresh_token)
51
+          setExpiresIn(res.expires_in)
52
+          commit('SET_EXPIRES_IN', res.expires_in)
42 53
           resolve()
43 54
         }).catch(error => {
44 55
           reject(error)
@@ -67,6 +78,23 @@ const user = {
67 78
       })
68 79
     },
69 80
     
81
+    // 刷新token
82
+    RefreshToken({commit, state}) {
83
+      return new Promise((resolve, reject) => {
84
+        refreshToken(state.refresh_token).then(res => {
85
+          setToken(res.access_token)
86
+          commit('SET_TOKEN', res.access_token)
87
+          setRefreshToken(res.refresh_token)
88
+          commit('SET_REFRESH_TOKEN', res.refresh_token)
89
+          setExpiresIn(res.expires_in)
90
+          commit('SET_EXPIRES_IN', res.expires_in)
91
+          resolve()
92
+        }).catch(error => {
93
+          reject(error)
94
+        })
95
+      })
96
+    },
97
+    
70 98
     // 退出系统
71 99
     LogOut({ commit, state }) {
72 100
       return new Promise((resolve, reject) => {

+ 28 - 0
ruoyi-ui/src/utils/auth.js

@@ -2,6 +2,10 @@ import Cookies from 'js-cookie'
2 2
 
3 3
 const TokenKey = 'Admin-Token'
4 4
 
5
+const RefreshTokenKey = 'Admin-Refresh-Token'
6
+
7
+const ExpiresInKey = 'Admin-Expires-In'
8
+
5 9
 export function getToken() {
6 10
   return Cookies.get(TokenKey)
7 11
 }
@@ -13,3 +17,27 @@ export function setToken(token) {
13 17
 export function removeToken() {
14 18
   return Cookies.remove(TokenKey)
15 19
 }
20
+
21
+export function getRefreshToken() {
22
+  return Cookies.get(RefreshTokenKey) || ``
23
+}
24
+
25
+export function setRefreshToken(token) {
26
+  return Cookies.set(RefreshTokenKey, token)
27
+}
28
+
29
+export function removeRefreshToken() {
30
+  return Cookies.remove(RefreshTokenKey)
31
+}
32
+
33
+export function getExpiresIn() {
34
+  return Cookies.get(ExpiresInKey) || -1
35
+}
36
+
37
+export function setExpiresIn(time) {
38
+  return Cookies.set(ExpiresInKey, time)
39
+}
40
+
41
+export function removeExpiresIn() {
42
+  return Cookies.remove(ExpiresInKey)
43
+}

+ 28 - 0
ruoyi-ui/src/views/index.vue

@@ -35,6 +35,7 @@ import LineChart from './dashboard/LineChart'
35 35
 import RaddarChart from './dashboard/RaddarChart'
36 36
 import PieChart from './dashboard/PieChart'
37 37
 import BarChart from './dashboard/BarChart'
38
+import { getToken, getExpiresIn, setExpiresIn } from '@/utils/auth'
38 39
 
39 40
 const lineChartData = {
40 41
   newVisitis: {
@@ -66,12 +67,39 @@ export default {
66 67
   },
67 68
   data() {
68 69
     return {
70
+      //刷新token锁
71
+      refreshLock: false,
72
+      //刷新token的时间
73
+      refreshTime: '',
69 74
       lineChartData: lineChartData.newVisitis
70 75
     }
71 76
   },
77
+  created() {
78
+    this.refreshToken()
79
+  },
72 80
   methods: {
73 81
     handleSetLineChartData(type) {
74 82
       this.lineChartData = lineChartData[type]
83
+    },
84
+    // 实时检测刷新token
85
+    refreshToken() {
86
+      this.refreshTime = setInterval(() => {
87
+        if (null === getToken()) {
88
+          return;
89
+        }
90
+        const expires_in = getExpiresIn();
91
+        if (expires_in <= 1000 && !this.refreshLock) {
92
+          this.refreshLock = true
93
+          this.$store
94
+            .dispatch('RefreshToken')
95
+            .catch(() => {
96
+              clearInterval(this.refreshTime)
97
+            });
98
+          this.refreshLock = false
99
+        }
100
+        this.$store.commit("SET_EXPIRES_IN", expires_in - 10);
101
+        setExpiresIn(expires_in - 10);
102
+      }, 10000);
75 103
     }
76 104
   }
77 105
 }