登录解决方案-单体应用-Session登录(拦截器实现)-Aop加自定义注解 对每个接口进行访问控制
一、需求实现
一、Aop加自定义注解 对每个接口进行访问控制
1、加一个从Session里面查出用户信息的接口
package com.mangoubiubiu.controller;
import com.mangoubiubiu.annotation.Auth;
import com.mangoubiubiu.entities.HuasUser;
import com.mangoubiubiu.event.SessionIdEvent;
import com.mangoubiubiu.exception.BusinessException;
import com.mangoubiubiu.exception.CommonErrorCode;
import com.mangoubiubiu.service.LoginService;
import com.mangoubiubiu.utils.R;
import com.mangoubiubiu.vo.UserLogin;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@Api(tags = "登录模快")
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class LoginController {
final ApplicationEventPublisher context;
final LoginService loginService;
@ApiImplicitParam(name = "userLogin",value = "用户信息",required = true)
@ApiOperation(value = "登录接口")
@PostMapping("/login")
public R login(@RequestBody UserLogin userLogin){
boolean flag = false;
String type = userLogin.getType();
if(StringUtils.isBlank(type)){
throw new BusinessException(CommonErrorCode.E_100101);
}
//账号密码登录
if("0".equals(type)){
flag= loginService.loginByPwd(userLogin);
//验证码登录
}else if("1".equals(type)){
flag= loginService.loginByPhone(userLogin);
}
return flag==true?R.ok():R.error().message("登录失败");
}
@ApiImplicitParam(name = "userLogin",value = "查询用户信息",required = true)
@ApiOperation(value = "查询用户信息")
@GetMapping("/msg")
public R mgs(){
HuasUser user= loginService.getUserMsg();
return R.ok().data("list",user);
}
}
2、测试
发现查询到了,因为直接请求没有带JSESSIONid 过去,取不到Session 所有Session里也没有用户信息 就为null
3、用AOP 加自定义注解做登录校验
package com.mangoubiubiu.annotation;
import java.lang.annotation.*;
/**
* @author mangoubiubiu
*/
//作用在类,方法,字段上
@Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)//注解可以在运行期的加载阶段被加载到Class对象中。那么在程序运行阶段,我们可以通过反射得到这个注解,并通过判断是否有这个注解或这个注解中属性的值,从而执行不同的程序代码段
@Documented//是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。
public @interface Auth {
}
package com.mangoubiubiu.aspect;
import com.mangoubiubiu.entities.HuasUser;
import com.mangoubiubiu.enums.SessionCodeEnum;
import com.mangoubiubiu.service.SessionService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
@Aspect
@Component
@Slf4j
@AllArgsConstructor
public class AuthAspect {
final SessionService sessionService;
/**
* 切入点
*/
@Pointcut("@annotation(com.mangoubiubiu.annotation.Auth)")
public void pointCut(){}
/**
* 前置通知 在目标方法 运行前执行
* @param joinpoint
*/
@Before("pointCut()")
public void logStart(JoinPoint joinpoint) throws ServletException, IOException {
HuasUser huasUser = (HuasUser) sessionService.getSessionByKey(SessionCodeEnum.USER_INFO.getKey());
if(huasUser == null){
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();
//跳转至主页
request.getRequestDispatcher("/mvc/index").forward(request,response);
}
}
}
4、接口上标上自定义注解 再测试
@Auth
@ApiImplicitParam(name = "userLogin",value = "查询用户信息",required = true)
@ApiOperation(value = "查询用户信息")
@GetMapping("/msg")
public R mgs(){
HuasUser user= loginService.getUserMsg();
return R.ok().data("list",user);
}
直接转发到登录页 成功,如果是前后分离话AOP 那里不转发,可以利用环绕通知给个 用户未登录的标识,要前端拿这个标识做跳转。
本文作者:KwFruit
本文链接:https://www.cnblogs.com/mangoubiubiu/p/16102664.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
深入理解登录
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步