JustAuth practical document - Basic chapter

JustAuth actual combat document

JustAuth, as you can see, is just a tool class library for third-party authorized login. It can let us get rid of the tedious third-party login SDK and make the login So easy! This column will introduce in detail how to use JustAuth to realize third-party login and how to use the advanced features of JustAuth.

🎉 Initializing a project with SpringBoot

Before the tutorial officially starts, we need to prepare the corresponding software environment. JustAuth

Use the following methods to create a project under IDEA: click file new project in turn and select Spring Initializr. Operate according to the prompts. Check two dependencies spring boot starter web and lombok when configuring dependencies. In order to facilitate development and testing, I select a spring boot devtools here.

After the prompt is completed, the POM is as follows

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>me.zhyd.justauth</groupId>
    <artifactId>justauth-tutorial</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>justauth-tutorial</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

After the project is compiled, we start to formally integrate JustAuth.

➕ Add JustAuth dependency

Before the official start, it is suggested that friends first look at JustAuth's user documentation: https://docs.justauth.whnb.wang , focusing on the quick start chapter.

This chapter contains important information about OAuth and JustAuth. Again, it is recommended to view this chapter first.

Again, there are three steps to using JustAuth (these three steps are also suitable for any platform supported by JustAuth):

  1. Apply to register the developer account of the third-party platform
  2. Create the application of the third-party platform and obtain the configuration information (accessKey, secretKey, redirectUri)
  3. Use this tool to realize authorized login

Of course, it doesn't matter who is the first in the third step or the first two steps. You can implement the code first and then apply for the third-party application, or you can apply for the third-party application first and then integrate the code.

Next we follow file The first step on indicates that pom dependencies are added first.

<dependency>
    <groupId>me.zhyd.oauth</groupId>
    <artifactId>JustAuth</artifactId>
    <version>1.15.1</version>
</dependency>

After the dependency is added, wait for the compilation of the project to complete, and then we will start to officially access JustAuth.

➕ API for JustAuth integration

Note that in the following code, our request link is obtained through the dynamic parameter {source}, so that we can easily integrate any platform. For example, when integrating gitee, our request address is: http://localhost:8080/oauth/render/gitee , and the callback address is http://localhost:8080/oauth/callback/gitee.

Of course, the example just tells you that you can use it, but if you only need to integrate a single platform, you can directly change {souce} to the platform name, such as gitee

package me.zhyd.justauth;

import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Practical demonstration of how to use JustAuth to realize third-party login
 *
 * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
 * @version 1.0.0
 * @since 1.0.0
 */
@RestController
@RequestMapping("/oauth")
public class JustAuthController {

    /**
     * Get the authorization link and jump to the third party authorization page
     *
     * @param response response
     * @throws IOException response Possible exceptions
     */
    @RequestMapping("/render/{source}")
    public void renderAuth(HttpServletResponse response) throws IOException {
        AuthRequest authRequest = getAuthRequest();
        String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
        response.sendRedirect(authorizeUrl);
    }

    /**
     * After the user confirms the authorization (login) of the third-party platform, the third-party platform will be redirected to the address and carry the code, state and other parameters
     *
     * @param callback Input parameter when the third party callback
     * @return User information of the third party platform
     */
    @RequestMapping("/callback/{source}")
    public Object login(AuthCallback callback) {
        AuthRequest authRequest = getAuthRequest();
        return authRequest.login(callback);
    }

    /**
     * Get authorization Request
     *
     * @return AuthRequest
     */
    private AuthRequest getAuthRequest() {
        return new AuthGiteeRequest(AuthConfig.builder()
                .clientId("clientId")
                .clientSecret("clientSecret")
                .redirectUri("redirectUri")
                .build());
    }

}

Next, we need to create our OAuth application on gitee. After logging in to gitee, we click the user's image in the upper right corner, select settings, then click the third-party application to enter the third-party application management page, and click the create application button in the upper right corner to enter the application creation page

We can fill in our application information according to the prompts.

Application Name: generally fill in your own website name

Application Description: generally fill in your own application description

Application homepage: fill in the homepage address of your website

Application callback address: important. The address is the address of the website to which users need to jump after authorization. A code parameter is carried by default

Permission: according to the page prompt, the first one is checked by default, because we only need to obtain user information

After the above information is input, click OK to create the application. After creation, click to enter the application details page, where you can see the application key and other information

Copy the following three information: Client ID, Client Secret, and application callback address.

➕ Custom HTTP tools

Get the previous step to the configuration information configuration AuthConfig, as follows:

private AuthRequest getAuthRequest() {
        return new AuthGiteeRequest(AuthConfig.builder()
                .clientId("4c504cd2e1b1dbaba8dc1187d8070adf679acab17b2bc9cf6dfa76b9ae06aadc")
                .clientSecret("fa5857175723475e4675e36af9eafde338545c1a0dfa49d1e0cc78f9c3ce5ebe")
                .redirectUri("http://localhost:8080/oauth/callback/gitee")
                .build());
    }

}

After the above work is completed, we will start the project directly, and then visit http://localhost:8080/oauth/render/gitee , when the following page appears, it means that we have successfully integrated and have jumped to the third-party authorization page.

Note that if you have not logged in your account in the browser, you will see the following page:

After we click "agree to authorize", the third-party application (Gitee) will generate a code authorization code, which will be called back to our configured redirectUri interface together with the state we passed on first.

As shown in the figure above, after entering the callback interface, we can trace the information returned by the third-party platform: state and code.

If you are a new project, there may be a small problem:

2020-04-21 23:50:02 http-nio-8080-exec-4 me.zhyd.oauth.log.Log(error:45) [ERROR] - Failed to login with oauth authorization.
com.xkcoding.http.exception.SimpleHttpException: HTTP Implementation class not specified!
    at com.xkcoding.http.HttpUtil.checkHttpNotNull(HttpUtil.java:70)
    at com.xkcoding.http.HttpUtil.post(HttpUtil.java:119)
    at me.zhyd.oauth.request.AuthDefaultRequest.doPostAuthorizationCode(AuthDefaultRequest.java:213)
    at me.zhyd.oauth.request.AuthGiteeRequest.getAccessToken(AuthGiteeRequest.java:31)
    at me.zhyd.oauth.request.AuthDefaultRequest.login(AuthDefaultRequest.java:79)
    at me.zhyd.justauth.JustAuthController.login(JustAuthController.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

This is because JustAuth v1.14.0 Start integrating by default simple-http As a general HTTP interface (for update instructions, see Justauth version 1.14.0 is officially released! Perfect decoupling HTTP tool )In view of the integration of HTTP tools in general projects, such as OkHttp3, apache HttpClient, hutool HTTP, in order to reduce unnecessary dependence, the v1.14.0 At the beginning, JustAuth will not integrate hutool HTTP by default. If the developer's project is brand new or there is no integrated HTTP implementation tool in the project, corresponding HTTP implementation classes need to be added. JustAuth provides three alternative pom dependencies:

hutool-http

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-http</artifactId>
    <version>5.2.5</version>
</dependency>

httpclient

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.5.12</version>
</dependency>

okhttp

<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
  <version>4.4.1</version>
</dependency>

After adding HTTP tool dependency, restart the project and access again http://localhost:8080/oauth/render/gitee Link, and then authorize.

After authorization, you will see the following page:

Tags: Java Apache Spring Maven

Posted on Thu, 11 Jun 2020 03:53:17 -0400 by daena76