目标
?上一章节手撸SSO单点登录(四)登录验证-首次登录已经成功登陆并且跳转至OA系统,当OA系统刷新,或者OA系统打开其他菜单是怎么实现无需登陆,直接验证通过,跳转页面或者刷新页面。 视频详细讲解请见https://www.bilibili.com/video/BV1b5411d7be/ 代码下载地址
二 、系统UML工程类图
三、代码实现
a.当刷新OA系统页面的时候,进入com.yuantai.filter.LoginFilter 请求拦截、进入isAccessAllowed 方法
@Override
public boolean isAccessAllowed(HttpServletRequest request, HttpServletResponse response) throws IOException {
SessionAccessToken sessionAccessToken = SessionUtils.getAccessToken(request);
// 本地Session中已存在,且accessToken没过期或者refreshToken成功,直接返回
if (sessionAccessToken != null && (!sessionAccessToken.isExpired()
|| refreshToken(sessionAccessToken.getRefreshToken(), request))) {
return true;
}
String code = request.getParameter(Oauth2Constant.AUTH_CODE);
if (code != null) {
// 获取accessToken
getAccessToken(code, request);
// 为去掉URL中授权码参数,再跳转一次当前地址
redirectLocalRemoveCode(request, response);
}
else {
redirectLogin(request, response);
}
return false;
}
因之前已经登陆过,所以SessionUtils.getAccessToken(request) 取值不为空,进去到
if (sessionAccessToken != null && (!sessionAccessToken.isExpired()
|| refreshToken(sessionAccessToken.getRefreshToken(), request))) {
return true;
}
?当sessionAccessToken.isExpired() 没有过期 或者刷新refreshToken(sessionAccessToken.getRefreshToken(), request)) 成功返回true ,认证通过,进入com.yuantai.controller.IndexController 的"/" GET请求返回请求成功index 页面
b.如果sessionAccessToken.isExpired()过期,我们需要调用refreshToken(sessionAccessToken.getRefreshToken(), request)) 刷新token成功才会返回true。
protected boolean refreshToken(String refreshToken, HttpServletRequest request) {
Result<RpcAccessToken> result = Oauth2Utils.refreshToken(getServerUrl(), getAppId(), refreshToken);
if (!result.isSuccess()) {
logger.error("refreshToken has error, message:{}", result.getMessage());
return false;
}
return setAccessTokenInSession(result.getData(), request);
}
?可以看到Oauth2Utils.refreshToken(getServerUrl(), getAppId(), refreshToken); 这里是向认证中心请求token 刷新我们当做token 刷新成功(如果刷新不成功将会认证失败直接跳转到SSO统一登录页面,需要再次登录验证)。
接着调用 setAccessTokenInSession(result.getData(), request); 把登录信息存储到session中,记录session与token的映射关系(这里与手撸SSO单点登录(四)登录验证-首次登录根据临时授权码code获取登录信息后的流程一样)
private boolean setAccessTokenInSession(RpcAccessToken rpcAccessToken, HttpServletRequest request) {
if (rpcAccessToken == null) {
return false;
}
// 记录accessToken到本地session
SessionUtils.setAccessToken(request, rpcAccessToken);
// 记录本地session和accessToken映射
recordSession(request, rpcAccessToken.getAccessToken());
return true;
}
总结 刷新页面,或者打开新的页面,无非就是带着登录后的信息去后台请求接口,第一步先去验证是否通过,验证通过则继续接口调用,验证不通过直接跳转至SSO统一登录页面。
|