spring security+oauth2退出登录(一)-正常的退出登录

流程

spring security+oauth2退出登录(一)-正常的退出登录_第1张图片

 

详细代码

/logout

1.vue前台点击退出登录,调用/logout接口,/logout接口使用thymeleaf跳转到logout.html页面

@Controller
public class LogoutController {

    /**
     * 正常退出登录接口
     * 
     * @param clientId
     * @param accessToken
     * @return
     */
    @GetMapping("/logout/page")
    public ModelAndView logout(String clientId, String accessToken) {
        Map data = new HashMap<>();
        data.put("clientId", clientId);
        data.put("accessToken", accessToken);
        return new ModelAndView("/logout", data);
    }
}

logout.html

logout.html并没有显示 只有两个逻辑 1.调用退出登录的接口 去清除token和session

                                                           2.调用获取授权码接口 重写跳转到login页面




    
    
    
    vue模板
    
    
    
    
    
    


OauthController 

清除token与session接口

这里实现了单点登录 我们在redis查询相同用户,相同ip,相同浏览器的token 全部失效

同时我们必须清除cookie 因为在调用接口时 我们使用token判断是否有权限 但是在登录时 确是以session与cookie来确认登录状态 后台会保存session 如果在获取授权码时携带的是已经登录的cookie 那么就不会再次登录 直接获取授权码 这样是错误的!

所以 我们在退出登录时也需要清除session与cookie 保证下次登录时需要输入账号密码

此处有跨域的问题 只有转跳到后端页面才能清除后端的session 这个是logout.html存在的目的

@RestController
@RequestMapping("/oauth")
public class OauthController {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    @Lazy
    private TokenStore tokenStore;

    @Autowired
    private TokenEndpoint tokenEndpoint;

    @Autowired
    private SessionRegistry sessionRegistry;

    @Autowired
    Utils utils;

    @GetMapping("/customLogout")
    public void logout(@RequestParam String access_token) throws IOException {
        if (StringUtils.isNotBlank(access_token)) {
            // 获取当前传入token信息
            OAuth2AccessToken inputAccessToken = tokenStore.readAccessToken(access_token);
            if (inputAccessToken != null) {
                // 获取ip和用户信息
                String ip = String.valueOf(inputAccessToken.getAdditionalInformation().get("client_Ip"));
                String user_name = String.valueOf(inputAccessToken.getAdditionalInformation().get("user_name"));
                String web_name = String.valueOf(inputAccessToken.getAdditionalInformation().get("web_name"));
                // 获取所有token
                List allToken = utils.getAllToken();
                for (OAuth2AccessToken oAuth2AccessToken : allToken) {
                    if (ip.equals(oAuth2AccessToken.getAdditionalInformation().get("client_Ip"))
                        && user_name.equals(oAuth2AccessToken.getAdditionalInformation().get("user_name"))
                        && web_name.equals(oAuth2AccessToken.getAdditionalInformation().get("web_name"))) {
                        // 这些token需要退出登录
                        tokenStore.removeAccessToken(oAuth2AccessToken);
                    }
                }
            }
            // 清除cookie
            HttpServletResponse response = utils.clearCookie();
            response.setStatus(HttpStatus.OK.value());
            response.setHeader("Content-Type", "application/json;charset=UTF-8");
            Result result = new Result(200, "退出登录成功");
            response.getWriter().write(new ObjectMapper().writeValueAsString(result));
        }
    }
}

 

你可能感兴趣的:(oauth2+spring,security)