# OAuth 2.0

## Introduction

* In order to access the third party's resource. Instead of just let the user access the all of resource directly, we need to approve the access right for the service by using limited number of service , due to the security issue

## Terminology

### Resource

* The resource of third-party, such as cloud storage...

### Resource Owner

* A person who can access the resource directly and grant the access&#x20;

### Resource Server

* The server of third party

### Client

* The application that want to apply the service of third party

### Authorization Server

* The server issuing access token to the client

## Flow

### Authorization Code Flow

![](/files/-MdfVJPoHp_dVKICAB8h)

* Firstly, the client server pass the registered client id, redirect url , scope (your requested access right), code challenge (optional, for preventing be hacked)
* If success, the auth server will return authorization code which is a param in url query
* Then, send the code  and code verifier (optional, unlock the code challenge to make sure the resource comes from the same origin) to the auth server to obtain access token(The access right of obtaining protected resource)  and refresh token (used to get another access token when the token is expired)&#x20;
* After getting access token, client can obtain the resource of third-party with help of the header containing access token

### Implicit Grant Flow

![](/files/-MdfXwCyxrn9cnrha4Yg)

* The flow is similar with authorization code flow, but this flow is to get access token from auth server directly instead of getting auth code and get the token from server by passing auth code
* This flow is not secured enough compared to authorization code flow

### Client Credential Flow

![](/files/-MdfZQEHwVeXxmQbUH6X)

* It is authorization between micro-services
* Since some of micro-services are not allowed other services to access all of their api end points, so they requires access in order to access their protected resources&#x20;

## Proof Key for Code Exchange (PKCE)

* In order to prevent from hacking
* Client will create their own secret key , called code verifier, and hash it to code challenge to auth server
* In order to proof the client is validated, client is needed to pass its code verifier with authorization code to auth server in order to get the access token

## Case Study (Google Login with React)

### Register client Id and redirect url on google console

![](/files/-MdfbVBndEom8kVtJBN7)

### Redirect the google login screen&#x20;

```javascript
import React from 'react'

const Main = () => {
    const loginAction = () => {
        const url = "https://accounts.google.com/o/oauth2/v2/auth?"
        + "scope=openid%20profile%20email&"
        + "response_type=code&"
        + "state=hi&"
        + "redirect_uri=http://localhost:3000/redirect&"
        + "client_id=xxxxxx"
        window.location.href = url;
    }
    return (
        <div>
          Main  
          <button onClick={loginAction}> Login</button>
        </div>
    )
}

export default Main
```

### Get the auth code and request access token

```javascript
import React,{useEffect} from 'react'
import {useLocation, useHistory} from "react-router-dom";
import qs from "query-string";
import axios from "axios";
const Redirect = () => {
    const {search} = useLocation();
    const history = useHistory();
    const {code: authCode} = qs.parse(search);
    console.log(authCode);

    useEffect(async()=>{
        try{
            const {data} = await axios.post("https://oauth2.googleapis.com/token",
            {
                client_id: "xxxx",
                code: authCode,
                grant_type: "authorization_code",
                redirect_uri: "http://localhost:3000/redirect",
                client_secret: "xxxxx"
            })
            localStorage.setItem("token",data.access_token);
            history.push("/success");
        }
        catch(err){
        }
    },[authCode])
    return (
        <div>
            Redirect
        </div>
    )
}

export default Redirect
```

### Obtain user information and revoke token (logout)

```javascript
import React,{useEffect} from 'react'
import axios from "axios";
import {useHistory} from "react-router-dom";
const Sucess = () => {
    const token = localStorage.getItem("token");
    const history = useHistory();
    useEffect(async()=>{
        const {data} = await axios.get(`https://www.googleapis.com/oauth2/v1/userinfo`,
        {headers: 
            {
            "Authorization": `Bearer ${token}`
        }});
        console.log(data);
    },[])
    const logoutAction = async() => {
        
        try{
            const {data} = await axios.post(`https://oauth2.googleapis.com/revoke?token=${token}`);
            history.push("/");
        }
        catch(error){
            console.log("logout error", error);
        }
    }
    return (
        <div>
            Success
            <button onClick={logoutAction}>logout</button>
        </div>
    )
}

export default Sucess
```

### Result

![Client](/files/-MdfceowxoyOWAlhxPVr)

![Google login](/files/-Mdfcobdl7N27dWjoYWC)

![Go to redirect url with code](/files/-MdfdQAzIPxwS_h_AkLO)

![Get the token](/files/-Mdfd7WkogML4WTSil6T)

![Obtain user info](/files/-Mdfd_RfnKk2JZ273VEn)

## Reference

{% embed url="<https://www.ruanyifeng.com/blog/2019/04/oauth_design.html>" %}

{% embed url="<https://ithelp.ithome.com.tw/articles/10227596>" %}

{% embed url="<https://www.youtube.com/watch?v=3pZ3Nh8tgTE>" %}

{% embed url="<https://developers.google.com/identity/protocols/oauth2/web-server#tokenrevoke>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://petercheng7788.gitbook.io/developer-note/backend/login/sso/oauth.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
