授权信息(登录信息)解析为接口方法的参数(@Authorization + HandlerMethodArgumentResolver + WebMvcConfigurer)

需求

对于需要授权或登录的系统,大量的接口,需要获取到用户的 授权信息 / 登录信息 。这些信息可能存在于Session或token中。

授权信息 / 登录信息解析为接口参数

这样避免了在每个接口中重复写信息解析的代码,提交了效率。

在这里插入图片描述

实现方式

  1. 注解:@Authorization
  2. 授权信息实体:Auth
  3. 参数解析器:HandlerMethodArgumentResolver
  4. 配置:WebMvcConfigurer

@Authorization:标记接口中的授权信息参数,用于确定要解析的接口参数;
授权信息实体:用来存储授权信息;
参数解析器:用来实现解析逻辑;
配置:将参数解析器,配置到Spring中。

核心代码

@Authorization

package com.example.core.authorization;

import java.lang.annotation.*;

/**
 * 授权信息-标记注解
 */
@Documented
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authorization {
}

Auth:授权信息实体

package com.example.core.authorization;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
@Schema(name = "授权信息")
public class Auth {

    @Schema(description = "登录ID", example = "1234567890123456789")
    private String loginId;

    @Schema(description = "登录账号", example = "1001")
    private String account;

}

HandlerMethodArgumentResolver

package com.example.core.authorization;

import com.example.core.authorization.constant.AuthConstant;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 授权信息参数解析器
 */
public class AuthorizationHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(Authorization.class) && parameter.getParameterType() == Auth.class;
    }


    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        return webRequest.getAttribute(AuthConstant.AUTHORIZATION, RequestAttributes.SCOPE_SESSION);
    }

}

WebMvcConfigurer

package com.example.core.config;

import com.example.core.authorization.AuthorizationHandlerMethodArgumentResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 * WebMvc配置器
 */
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new AuthorizationHandlerMethodArgumentResolver());
    }

}

补充代码

授权信息常量

package com.example.core.authorization.constant;

/**
 * 授权信息常量
 */
public class AuthConstant {

    /**
     * 授权信息 - Session.Attribute 的 name
     */
    public static final String AUTHORIZATION = "authorization";

}

测试

package com.example.web.account.controller;

import com.example.core.authorization.Auth;
import com.example.core.authorization.Authorization;
import com.example.core.authorization.constant.AuthConstant;
import com.example.web.account.model.ChangePasswordParam;
import com.example.web.account.model.LoginParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

@Slf4j
@RestController
@RequestMapping("accounts")
@Tag(name = "账号")
public class AccountController {

    @PostMapping("login")
    @Operation(summary = "登录")
    public void login(@Valid @RequestBody LoginParam param, HttpServletRequest request) {
        log.info("登录:LoginParam={}", param);

        Auth auth = new Auth();
        auth.setLoginId("1234567890123456789");
        auth.setAccount(param.getAccount());

        // 登录成功,记录用户的授权状态
        HttpSession session = request.getSession();
        session.setAttribute(AuthConstant.AUTHORIZATION, auth);
    }


    @PutMapping("change_password")
    @Operation(summary = "修改密码")
    @Parameter(name = "auth", hidden = true)
    public void changePassword(@Authorization Auth auth,
                               @Valid @RequestBody ChangePasswordParam param,
                               HttpServletRequest request) {
        log.info("修改密码:Authorization={}", auth);
        log.info("修改密码:ChangePasswordParam={}", param);
    }

}

效果

登录接口保存了授权信息;在其他接口,在已登录的前提下,能够从接口方法的参数中获得授权信息对象。

先调用登录接口,再调用修改密码接口,打印日志如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宋冠巡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值