Help us translate

This document is translated by the community. You can contribute on Crowdin. We appreciate your cooperation 🙏.

Obtaining an Access Token via OAuth

To get an access token for users (hereinafter simply referred to as "users") who will use your application, follow these steps:

Tips

The method described below is called OAuth 2.0. Unlike regular OAuth that requires app creation, this method can be used without creating an app through an extension called IndieAuth.

There are many libraries available for OAuth, so it is recommended to use one if possible.

Currently, a web page is required to use this method. If you cannot provide a web page or need to support versions of Misskey before 2023.9.0, please use one of the following methods:

Step 1

Create a webpage to introduce your app. Ensure the page is accessible via an HTTPS address. Include the following HTML code somewhere on the page:

<!-- (必須項目)hrefのアドレスが認証コードの転送先になります。 -->
<link rel='redirect_uri' href='/redirect'>

<!-- ユーザーに見せるアプリの名前になります。なかったらこのページのアドレスが名前になります。 -->
<div class='h-app'>
    <a href="/" class="u-url p-name">My Misskey App</a>
</div>

The authorization code will later be sent to the redirect_uri address.

Step 2

Generate the PKCE code_verifier and code_challenge strings, as well as a state string.

  • The code_verifier must be between 43 and 128 characters, containing only letters, digits, and the characters -._~.
  • The code_challenge is the code_verifier hashed with SHA256 and base64url encoded.
  • The state string has no special restrictions. Use a random string.
Danger

Generate new strings each time and do not reuse them.

Tips

It is recommended to use libraries like pkce-challenge or OAuth libraries with PKCE functionality.

import crypto from "node:crypto";

const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~";
const codeVerifier = new Array(128)
  .fill(0)
  .map(() => chars[Math.floor(chars.length * Math.random())])
  .join("");
console.log('code_verifier', codeVerifier);

const codeChallenge = crypto
  .createHash("sha256")
  .update(codeVerifier, "ascii")
  .digest("base64url");
console.log('code_challenge', codeChallenge);

const state = crypto.randomUUID();
console.log('state', state);

Step 3

Retrieve the OAuth information from the target server. The data is in JSON format.

https://{host}/.well-known/oauth-authorization-server

Replace {host} with the user's server host. Usually, the host is input by the user.

You will use the authorization_endpoint and token_endpoint in the next step.

Tips

You can also confirm the scope information with scopes_supported.

Step 4

Display the application authentication form in the user's browser. You can open the authentication form using a URL in the following format:

{authorization_endpoint}?client_id={client_id}&response_type=code&redirect_uri={redirect_uri}&scope={scope}&code_challenge={code_challenge}&code_challenge_method=S256&state={state}

Here,

  • Replace {authorization_endpoint} with the address obtained in the previous step.
  • Replace {client_id} with the address of your app's introduction page.
  • Replace {code_challenge} with the previously generated code_challenge string.
  • Set code_challenge_method to S256 (fixed).
  • Replace {redirect_uri} with the address used in your introduction page.
  • Replace {scope} with the permissions required by your application, separated by spaces. Use space , not commas. Check the list of permissions here.
  • Replace {state} with the previously generated state string.
https://misskey.local/oauth/authorize?client_id=http%3A%2F%2Fexample.com&code_challenge=C6hwMO2bmIzg3nqppTE9b79fvuOjlrKmH2xNiZSMHzw&code_challenge_method=S256&response_type=code&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect&scope=write%3Anotes&state=87c11f05-86eb-4eb2-9057-f6a98fc5e9ab

Step 5

Once the user grants access to the application, the user will be redirected to the page you specified as redirect_uri.

NameDescription
codeThe user's authorization code.
stateThe state string used in the authorization request.
https://example.com/redirect?code=...&state=87c11f05-86eb-4eb2-9057-f6a98fc5e9ab

Verify that the state string matches and proceed to the next step.

Step 6

Use the authorization code you get to request an access token via POST. The request is made to the token_endpoint. The data format can be either application/json or application/x-www-form-urlencoded. The parameters are as follows:

NameDescription
grant_typeAlways set to authorization_code.
client_idThe client_id string used in the authorization request.
redirect_uriThe redirect_uri string used in the authorization request.
scopeThe scope string used in the authorization request.
codeThe obtained authorization code.
code_verifierThe previously generated code_verifier string.
const res = await fetch(endpoint, {
  method: "POST",
  body: JSON.stringify({
    grant_type: "authorization_code",
    client_id: "https://example.com",
    redirect_uri: "https://example.com/redirect",
    scope: "write:notes",
    code: "...",
    code_verifier: "hjjbCYDmDpSLjirkO-PrfWKsRhDdJr-PAEGRClRwzUKlmFIIIrZNmSvUIraeIa~WqbqQnfbJV-Hc_IfuQkesBYUpukUi~lInDfU_AZjoZqbU.ioQTRzaFfZFfGnT-OAA",
  }),
  headers: {
    "Content-Type": "application/json"
  }
});

The response will be a JSON object from which you can obtain and use the access_token.