cookie+session+redis+springAop判断用户是否登录
2020-02-04 07:36
309 查看
采用前后端分离,后端只提供接口,前端对接口进行调用
1.前端用户发送登录请求
login.html
<div class="form-container sign-in-container"> <form action="#" id="l-form"> <h1>登录</h1> <span>或使用您的帐号</span> <input id="l-username" type="text" placeholder="用户名" name="username"> <input id="l-password" type="password" placeholder="密码" name="password"> <a href="#">忘记密码?</a> <button id="btn-login">登录</button> </form> </div>
login.js
$("#btn-login").click(function () { $.ajax({ url: "/api/login", type: "POST", data: { "username": $("#l-username").val(), "password": $("#l-password").val(), }, success: function (result) { //根据服务器端返回的结果进行相应处理 }); return false; });
2.服务器端将SessionId存入到Redis并将SessionId返回
ApiController.java
/** * method: post * url: /login * description: 登录 */ @PostMapping(Api.LOGIN) public Result login(String username, String password, HttpSession session) { User user = userService.selectUserByUsername(username); if (password != null && salt != null && realPassword.equals(user.getPassword())) { //存入redis key:username value:sessionId redisService.set(username, session.getId()); return Result.success().add("username", username).add("sessionId",session.getId()); } }
3.前端将SessionId保存到Cookie(这里使用到了jquery.cookie.js插件)
$.cookie(username, sessionId, {expires: 7, path: '/'});
4.前端必须是登录状态才能发送的请求(比如注销):
logout.js
function logout() { var username=window.location.href.split("?")[1].split("=")[1]; var sessionId=$.cookie(username); if(sessionId==null){ //如果cookie中没有sessionId则不能发送logout请求 alert(username+"尚未登录"); window.location.href="/user/index"; return; } $.ajax({ url: "/api/logout", type:"post", data: { username: username, sessionId:sessionId, //将sessionId也发送过去 }, success:function(result){ var errorCode=result.errorCode; var reason=result.reason; switch (errorCode) { case 8004: alert(reason); break; } window.location.href="/user/index"; } }) }
5.服务器端通过SpringAop对需要是登录状态才能进行的请求进行拦截,检查用户是否登录
LoginStatusAop.java
@Aspect @Component @Slf4j public class LoginStatusAop { @Autowired private RedisService redisService; //这里需要使用@Around而不要用@Before,因为@Before不能使用ProceedJoinPoint,只能使用JoinPoint. //而@Before的话即使你return了或者throw Exception还是会往下执行 //而@Around只有调用了proceed()才会往下执行 @Around(value = "doApi()") public Object doApiBefore( ProceedingJoinPoint pjp) throws Throwable { try{ Object[] args = pjp.getArgs(); String username = args[0].toString(); String sessionId = args[1].toString(); String realSessionId = redisService.get(username); //如果前端发送过来的sessionId和服务器端的sessionId一致才会请求到/logout api if(realSessionId!=null&&sessionId.equals(realSessionId)){ return pjp.proceed(); } }catch (Exception e){ return Result.failure(Constant.FAILURE_CODE,Constant.LOGIN_USER_IDLE_CODE,Constant.LOGIN_USER_IDLE); } return Result.failure(Constant.FAILURE_CODE,Constant.LOGIN_USER_IDLE_CODE,Constant.LOGIN_USER_IDLE); } //我将所有需要登录才能进行请求的api方法都设置为了protected //这里要注意不能设置为private,不然会无效,原因自行百度 //不知道此条切点表达式意思的话自行百度 @Pointcut("execution(protected * com.selenium.aaa.common.controller.ApiController.*(..))") public void doApi() { } }
6.服务器端在注销后删除Redis中的SessionId
ApiController
/** * method: post * url: /logout * description: 退出 */ @PostMapping(Api.LOGOUT) protected Result logout(String username,String sessionId) { if(redisService.delete(username)){ //删除redis中的sessionId return Result.success(); }else{ return Result.failure(); } }
注意:这样还是又一个问题,暂时不知道如何解决,当用户异常退出时(比如直接关闭浏览器),/logout没有被调用,导致redis中的sessionId没有被清除,我想到的办法只能给cookie和redis设置expire(超时),但显然这是有问题的。
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 基于SpringBoot简单实现SpringAop+Redis+cookie 单点登录 和 用户登录检测
- destoon 的登录过程,如何使用cookie来判断用户是否登录
- express学习-----使用session、cookie判断用户登录状态
- 在ASP.NET中怎么用SESSION判断用户是否登录?
- 认识cookie 一般运用在判断用户是否登录和购物车
- 在ASP.NET中用SESSION判断用户是否登录
- JSP透过session判断用户是否登录
- 利用Cookie保存用户登录信息,利用Filter来判断用户是否登录
- asp.net判断用户是否登录(SetAuthCookie相关问题)
- 在ASP.NET中怎么用SESSION判断用户是否登录?
- 在ASP.NET中怎么用SESSION判断用户是否登录?
- 在ASP.NET中怎么用SESSION判断用户是否登录?(原创)
- 在ASP.NET中怎么用SESSION判断用户是否登录?
- 在ASP.NET中怎么用SESSION判断用户是否登录
- 在ASP.NET中怎么用SESSION判断用户是否登录? 以及Session登陆后丢失的解决办法
- 在ASP.NET中怎么用SESSION判断用户是否登录
- spring session redis 单用户登录
- 检查session判断用户是否退出登录
- 判断用户session 是否过期,如果过期,让用户重新登录
- spring boot+spring security+thymeleaf在页面上判断用户是否登录