Skip to main content

refresh-token-auto-login

刷新token实现自动登录

在上一节课中,我们介绍了如何获取用户的登录状态以及如何处理Token的过期失效。默认情况下,我们使用的是access Token,并将其过期时间设置为5分钟。然而,如果用户在使用网站时每隔5分钟就需要重新登录一次,这对用户体验来说是非常糟糕的。因此,我们可以通过另一种方式实现自动登录,即使用Refresh Token来刷新Token的过期时间。

Refresh Token的默认过期时间是一天。当access token过期时,我们可以通过发送一个刷新请求来获取新的Token。在登录成功之后,我们将此刷新令牌存储在本地(例如localStorage)中。当access Token过期时,我们取出这个刷新令牌,并使用axios发送一个刷新请求,请求的数据中包含这个刷新令牌。如果刷新请求成功,我们将得到一个新的access token,将新的Token存储在本地,并更新Token的过期时间。如果刷新请求失败(例如刷新令牌过期),则用户需要重新登录。

我们可以根据需求来配置Token的过期时间和刷新令牌的过期时间。在项目的设置中,我们可以通过以下步骤进行配置:

  1. 打开项目的Settings文件。
  2. 定义两个参数:Token的过期时间和刷新令牌的过期时间。通常我们使用datetime.timedelta来定义时间间隔。
  3. 将Token的过期时间和刷新令牌的过期时间设置为合适的值。

下面是一个示例配置:

dx_movie/dx_movie/settings.py
from datetime import timedelta

JWT_ACCESS_TOKEN_EXPIRE_MINUTES = 60
JWT_REFRESH_TOKEN_EXPIRE_DAYS = datetime.timedelta(days=14)

这样,我们就设置了Token的过期时间为60分钟,刷新令牌的过期时间为14天。

然后,我们需要在代码中实现自动登录的功能。首先,我们需要在每个请求的Header中添加Token信息,并且在代码中判断Token是否过期。如果Token没有过期,我们继续执行后续操作,用户状态保持登录。如果Token过期了,我们就尝试使用刷新令牌来获取新的Token。下面是实现逻辑的示例代码:

frontend/src/components/Header.vue
<script>
import Category from '@/components/Category.vue'
import axios from 'axios'

export default {
name: 'Header',
data: function() {
return {
keyword: '',
username: '',
showMenu: false,
}
},
mounted() {
this.username = localStorage.getItem('username')
// 判断登录状态
const currentTime = Date.now()
const expiredTime = localStorage.getItem('expiredTime')
const refreshToken = localStorage.getItem('refreshToken')

if (expiredTime > currentTime) {
this.$store.commit('setLoginStatus', true)
}
else if (refreshToken) {
axios
.post('/api/jwt/refresh/', {refresh: refreshToken})
.then(response => {
console.log('执行refresh')
const token = response.data.access
localStorage.setItem("token", token)
// 更新过期时间
const expiredTime = Date.now() + 5 * 60 * 1000
localStorage.setItem('expiredTime', expiredTime)
this.$store.commit('setLoginStatus', true)
})
.catch( error => {
console.log(error)
this.$store.commit('setLoginStatus', false)
localStorage.clear()
})

}
else {
this.$store.commit('setLoginStatus', false)
localStorage.clear()
}
},
components: { Category },
methods: {
searchMovies(){
const keyword = this.keyword.trim() //去除空格
this.$router.push({
name: 'home',
query: { search: keyword}
})
},
// 切换展示和隐藏
toggleMenu() {
this.showMenu = !this.showMenu
},
},
}
</script>

在以上代码中,axios.post('/api/jwt/refresh', { refresh: refreshToken })是发送刷新请求的示例代码。在请求成功时,我们将获得的新Token存储在本地,并更新Token的过期时间。在请求失败时,我们清空本地的数据,并需要用户重新登录。

通过以上步骤,我们就实现了使用Refresh Token来实现自动登录的功能。

注意:在实际项目中,请根据实际情况做出相应的安全措施,例如对刷新请求进行身份验证,限制请求次数等。

希望本节课程对大家有所帮助,我们下节再见。