【问题标题】:JSON Web Token (JWT): should I use response header or body for token transportation?JSON Web 令牌 (JWT):我应该使用响应标头还是正文进行令牌传输?
【发布时间】:2020-12-24 21:50:35
【问题描述】:

我正在开发一个 RESTful Web 服务,它以 JSON Web 令牌 (JWT) 的形式发布访问令牌,以便客​​户端可以使用它们进行进一步授权。目前,我将令牌存储在响应正文中,但通常建议将其添加到 Authorization 标头中。为什么我应该选择标题而不是响应正文?使用一种方法比另一种方法有什么主要优势吗?

@RestController
@RequestMapping(path = "/auth", produces = "application/json")
public class AccessTokenController {

    @Value("${jwt.secret.key.gen}")
    private String secretKey;

    @Value("${jwt.expiration.days}")
    private int expirationDays;

    private final UsersRepository usersRepository;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public AccessTokenController(UsersRepository usersRepository, PasswordEncoder passwordEncoder) {
        this.usersRepository = usersRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @PostMapping(value = "/access-token", consumes = "application/json")
    ResponseEntity<Object> getAccessToken(@RequestBody Map<String, String> credentials) {

        // #1: check request body for username and password
        String username = credentials.get("username");
        String password = credentials.get("password");
        if (username.isBlank() || password.isBlank())
            throw new IllegalArgumentException();

        // #2: check database for given username and password
        User user = usersRepository.findByUsername(username)
                .filter(u -> passwordEncoder.matches(password, u.getPassword()))
                .orElseThrow(() -> new BadCredentialsException("No such user with given password"));

        // #3: check 'enabled' status for the requested user
        if (!user.isEnabled())
            throw new DisabledException("User is currently disabled");

        // # 4: create and return access-token (finally!)
        String token = Jwts.builder()
                .setSubject(username)
                .setExpiration(new Date(System.currentTimeMillis() + expirationDays * 24 * 60 * 60 * 1000))
                .signWith(SignatureAlgorithm.HS512, secretKey.getBytes())
                .compact();
        return new ResponseEntity<>(Collections.singletonMap("access-token", token),
                HttpStatus.OK);
    }

    @ExceptionHandler({JsonParseException.class, NullPointerException.class, IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String, String> handleWrongOrMissingCredentials() {
        return Collections.singletonMap("error", "Wrong or missing credentials");
    }

    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public Map<String, String> handleAuthenticationException(AuthenticationException ex) {
        return Collections.singletonMap("error", ex.getMessage());
    }

}

【问题讨论】:

    标签: java spring rest jwt


    【解决方案1】:

    它是所有 api 都遵循的 HTTP 标准的一部分。基本上,想出一套每个人都遵循的规则,这样当人们开发服务器或客户端时,他们就可以遵循这套规则以避免差异

    RFC https://www.rfc-editor.org/rfc/rfc7235#section-4.2

    “授权”标头字段允许用户代理进行身份验证
    本身带有源服务器——通常但不一定是在
    之后 收到 401(未经授权)响应。它的价值包括
    包含用户身份验证信息的凭据
    被请求资源领域的代理。

     Authorization = credentials
    

    人们现在可以使用许多不同类型的授权标头,一旦您使用它,您就会知道会发生什么。这是一个简单的列表来展示一些

           •    Basic Auth
           •    Bearer Token
           •    API Key
           •    Digest Auth
           •    Oauth 2.0
           •    Hawk Authentication
           •    AWS Signature
    

    【讨论】:

      猜你喜欢
      • 2016-03-08
      • 2016-08-01
      • 2020-11-16
      • 2017-09-15
      • 2017-02-23
      • 2020-09-29
      • 2021-04-20
      • 2020-11-30
      • 2019-03-27
      相关资源
      最近更新 更多