HarmonyOS 鸿蒙Next如何实现类似iOS token无感刷新功能
HarmonyOS 鸿蒙Next如何实现类似iOS token无感刷新功能
实现token无感刷新为了优化用户体验,当token过期时不需要用户跳回登录页重新登录,而是当token失效时,进行拦截,发送刷新token的请求,获取最新的token进行覆盖,让用户感受不到token已经过期
想实现的方案:在相应其中拦截,判断token返回过期后,调用刷新token的接口,然后自动重连刚刚token过期接口
3 回复
Demo如下:
import rcp from '@hms.collaboration.rcp';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
//拦截器接收数据对象
class ResponseCache {
private readonly cache: Record<string, rcp.Response> = {};
getResponse(url: string): rcp.Response {
return this.cache[url];
}
setResponse(url: string, response: rcp.Response): void {
this.cache[url] = response;
}
}
let storage: LocalStorage = new LocalStorage();
async function refreshToken(): Promise<string> {
// 发送请求获取并返回token
const response = await rcp.createSession().post('https://your-server.com/refresh-token');
if (response.statusCode === 200) {
// 注意这里需要返回实际获取的token
return 'response.refreshToken';
} else {
throw new Error('Failed to refresh token');
}
}
//自定义拦截器
class ResponseCachingInterceptor implements rcp.Interceptor {
private readonly cache: ResponseCache;
constructor(cache: ResponseCache) {
this.cache = cache;
}
//拦截器获取数据方法定义
intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
// 缓存
const url = context.request.url.href;
const responseFromCache = this.cache.getResponse(url);
if (responseFromCache) {
return Promise.resolve(responseFromCache);
}
const promise = next.handle(context);
promise.then((resp) => {
if (resp.statusCode == 401) { // Token 过期
try {
refreshToken().then((newToken) => {
if (context.request.headers) {
context.request.headers.authorization = 'Bearer ' + newToken
// 重新用新的token发送原始请求
const retryResponse = next.handle(context);
retryResponse.then(res => {
return retryResponse
})
}
})
} catch (error) {
// 处理重新发送失败的请求
}
}
this.cache.setResponse(url, resp);
});
return promise;
}
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
testUrl = "https://www.baidu.com"
//get请求方式获取数据
rcpGetData() {
let testUrl = this.testUrl
//定义通信会话对象
const sessionConfig = rcp.createSession();
//get请求
sessionConfig.get(testUrl).then((response) => {
hilog.info(0x0000, 'testTag', "test---------" + JSON.stringify(response));
//页面展示请求结果
AlertDialog.show(
{
title: 'request接口回调结果',
message: '请求网站:' + testUrl + '\n\n' + 'Callback Data: ' + JSON.stringify(response),
})
}).catch((err: BusinessError) => {
AlertDialog.show(
{
title: 'request接口回调结果',
message: '请求失败,错误信息:' + err.data,
})
hilog.error(0x0000, 'testTag', "test err:" + JSON.stringify(err));
});
}
//拦截器
getDataByInterceptor() {
const cache = new ResponseCache();
const session = rcp.createSession({
interceptors: [new ResponseCachingInterceptor(cache)]
});
session.get(this.testUrl).then((response) => {
hilog.info(0x0000, 'testTag', 'get requestData :' + JSON.stringify(response.request))
hilog.info(0x0000, 'testTag', 'get headersData :' + JSON.stringify(response.headers))
}).catch((err: BusinessError) => {
hilog.info(0x0000, 'testTag', `err: err code is ${err.code}, err message is ${err.message}`);
});
}
build() {
Row() {
Column() {
//get请求方式获取数据
Button('getData')
.onClick(() => {
this.rcpGetData();
})
.type(ButtonType.Capsule)
.margin({ top: 4 })
.backgroundColor('#ff1198ee')
.width('67%')
.height('4%')
}
.width('100%')
}
.height('100%')
}
}
HarmonyOS 鸿蒙Next要实现类似iOS的token无感刷新功能,可以通过以下方式实现:
首先,鸿蒙系统需支持在API接口请求时自动携带token进行身份验证。当token过期导致请求失败(如返回401状态码)时,系统应能自动拦截这一错误响应。
接着,系统可利用存储的refresh_token,在后台静默地调用刷新token的接口。成功获取新token后,系统需自动替换掉本地存储的过期token,并重新尝试之前失败的请求,确保用户无感知地完成整个过程。
此外,为确保刷新token的有效性,系统还需处理refresh_token过期的情况。一旦refresh_token也过期,系统应清除所有相关token信息,并引导用户重新登录。
请注意,实现该功能需后端配合提供刷新token的接口,并返回必要的token信息。同时,前端需妥善管理token的存储和更新逻辑。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。