小白也能懂的 linuxdo oauth2 快速上手

前言

将上面的java重新整理一下

依赖

所需依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>demo-OAuth2</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.3</version>
        <relativePath/>
    </parent>

    <dependencies>
        <!-- Spring Boot Starter Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

配置

application.yml
server:
  port: 8181

linux-do:
  oauth2:
    client:
      registration:
        client-id: hi3geJYfTotoiR5S62u3rh4W5tSeC5UG
        client-secret: VMPBVoAfOB5ojkGXRDEtzvDhRLENHpaN
        redirect-uri: http://localhost:8181/oauth2/callback
        authorization-grant-type: authorization_code
        scope: read,write
      provider:
        authorization-uri: https://connect.linux.do/oauth2/authorize
        token-uri: https://connect.linux.do/oauth2/token
        user-info-uri: https://connect.linux.do/api/user
        user-name-attribute: id

主要代码

代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Map;

@RestController
@RequestMapping("/oauth2")
public class OAuth2Controller {

    @Value("${linux-do.oauth2.client.registration.client-id}")
    private String clientId;

    @Value("${linux-do.oauth2.client.registration.client-secret}")
    private String clientSecret;

    @Value("${linux-do.oauth2.client.registration.redirect-uri}")
    private String redirectUri;

    @Value("${linux-do.oauth2.client.provider.authorization-uri}")
    private String authorizationEndpoint;

    @Value("${linux-do.oauth2.client.provider.token-uri}")
    private String tokenEndpoint;

    @Value("${linux-do.oauth2.client.provider.user-info-uri}")
    private String userEndpoint;

    @GetMapping("/initiate")
    public void initiateAuth(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        String state = new BigInteger(130, new SecureRandom()).toString(32);
        session.setAttribute("oauth2State", state);
        response.sendRedirect(String.format("%s?client_id=%s&response_type=code&redirect_uri=%s&scope=%s&state=%s",
                authorizationEndpoint, clientId, redirectUri, "read,write", state));
    }

    @GetMapping("/callback")
    public String handleAuthorizationCode(@RequestParam("code") String code, @RequestParam("state") String state, HttpServletRequest request) {
        String sessionState = (String) request.getSession().getAttribute("oauth2State");
        if (sessionState == null || !sessionState.equals(state)) {
            return "State mismatch error";
        }
        // 创建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        String auth = clientId + ":" + clientSecret;
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
        headers.add("Authorization", "Basic " + encodedAuth);

        // 使用授权码请求访问令牌
        MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
        requestBody.add("grant_type", "authorization_code");
        requestBody.add("code", code);
        requestBody.add("redirect_uri", redirectUri);

        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<Map> response = restTemplate.postForEntity(tokenEndpoint, requestEntity, Map.class);

        Map<String, Object> responseBody = response.getBody();

        // 处理响应,例如提取和返回访问令牌
        if (responseBody != null && responseBody.containsKey("access_token")) {
            HttpHeaders userHeaders = new HttpHeaders();
            userHeaders.setBearerAuth(responseBody.get("access_token").toString());
            HttpEntity<String> entity = new HttpEntity<>(userHeaders);
            ResponseEntity<Map> userResponse = restTemplate.exchange(userEndpoint, HttpMethod.GET, entity, Map.class);

            Map<String, Object> userResBody = userResponse.getBody();
            if (userResBody != null) {
                return userResBody.toString();
            } else {
                return "Failed to obtain user details";
            }
        } else {
            return "Failed to obtain access token";
        }
    }
}

注意

代码为demo代码,实际请根据自己所需对token进行处理

6 个赞