登录解决方案-单体应用-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 中国大陆许可协议进行许可。

posted @   KwFruit  阅读(82)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起