Skip to content

feat(backend): support OAuth 2.0 authorization#11053

Merged
syuilo merged 14 commits intodevelopfrom
oauth
Jul 27, 2023
Merged

feat(backend): support OAuth 2.0 authorization#11053
syuilo merged 14 commits intodevelopfrom
oauth

Conversation

@saschanaz
Copy link
Member

@saschanaz saschanaz commented Jun 28, 2023

What

Fixes #8262

Why

要望が多いそうです

Additional info (optional)

  1. app登録を使わず、IndieAuthの方式でclient_idのURLからアプリ情報を取得する。というわけでウェブページを持つ必要がある(そのページでローカルスキーマのredirect_urlを指定できる)
  2. クライアント側でPKCE(code_challenge)機能が要求される
  3. miauthのtokenとoauthのtokenの区別はしない(してもセキュリティの強化には繋がらないし余計に複雑になると思って)

Checklist

  • Read the contribution guide
  • Test working in a local environment
  • (If needed) Add story of storybook
  • (If needed) Update CHANGELOG.md
  • (If possible) Add tests

@github-actions github-actions bot added packages/backend Server side specific issue/PR packages/backend:test packages/frontend Client side specific issue/PR labels Jun 28, 2023
@github-actions github-actions bot requested review from syuilo and tamaina June 28, 2023 22:11
@codecov
Copy link

codecov bot commented Jun 28, 2023

Codecov Report

Merging #11053 (381bc86) into develop (c2370a1) will decrease coverage by 0.72%.
The diff coverage is 94.74%.

❗ Current head 381bc86 differs from pull request most recent head 93acaa5. Consider uploading reports for the commit 93acaa5 to get more accurate results

@@             Coverage Diff             @@
##           develop   #11053      +/-   ##
===========================================
- Coverage    78.58%   77.86%   -0.72%     
===========================================
  Files          918      921       +3     
  Lines        97212    93229    -3983     
  Branches      7751     7836      +85     
===========================================
- Hits         76390    72595    -3795     
+ Misses       20822    20634     -188     
Files Changed Coverage Δ
.../backend/src/server/oauth/OAuth2ProviderService.ts 94.60% <94.60%> (ø)
packages/backend/src/server/ServerModule.ts 100.00% <100.00%> (ø)
packages/backend/src/server/ServerService.ts 49.21% <100.00%> (-0.40%) ⬇️
packages/frontend/src/components/MkButton.vue 85.15% <100.00%> (-0.06%) ⬇️
packages/frontend/src/router.ts 99.24% <100.00%> (-0.01%) ⬇️

... and 914 files with indirect coverage changes

@saschanaz saschanaz marked this pull request as draft June 29, 2023 01:11
@saschanaz saschanaz marked this pull request as ready for review June 29, 2023 10:09
@github-actions github-actions bot requested a review from acid-chicken June 29, 2023 10:11
@saschanaz
Copy link
Member Author

@github-actions github-actions bot requested a review from acid-chicken

draftとready for review間の変更を続けたら全リビュアーにリクエストできるってこと?!

@syuilo
Copy link
Member

syuilo commented Jul 1, 2023

サンプルOAuthクライアント作って試してみる

@syuilo
Copy link
Member

syuilo commented Jul 1, 2023

知識がOAuth1.0で止まっているのとOAuth自体長らく触ってなかったから難航してる

@syuilo
Copy link
Member

syuilo commented Jul 1, 2023

NodejsのOAuth2.0クライアントについて調べると高確率でexpressとか出てくるんだけどクライアントにWebサーバーって必須じゃないよね?(このPRのものでは必須かもしれないけど)

@tamaina
Copy link
Contributor

tamaina commented Jul 1, 2023

ミリしらだけどリダイレクト先が必要=Webサーバーが必要なのでは

@syuilo
Copy link
Member

syuilo commented Jul 1, 2023

今までOAuthクライアント作ってたときわざわざWebサーバー建ててた記憶がない

@syuilo
Copy link
Member

syuilo commented Jul 1, 2023

でもリダイレクト必要なら建てるしかないか

@acid-chicken
Copy link
Member

例えば PC のネイティブアプリだとlocalhost にリダイレクト張りがち

@saschanaz
Copy link
Member Author

ミリしらだけどリダイレクト先が必要=Webサーバーが必要なのでは

カスタムスキーマ使えるので必修ではありません(このPRでは必要ですが適当にGitHub Pagesとか使っていいと思います)

@saschanaz
Copy link
Member Author

カスタムスキーマのサポートはまだないと言いましたが実は問題なかったので説明を直しました(でもテストはちょっと混乱)

  • client_idはHTTPSだけ許される
  • でもredirect_uriはそのページで何でも指定できる
    • ハッカーのサーバーに指定したりしたらこまるのでclient_idは自分自身だけ管理できるページURLを使うべき

@saschanaz
Copy link
Member Author

saschanaz commented Jul 1, 2023

テスト用クライアントです

(ローカルサーバーえのアクセスのためにクライアント側でNODE_TLS_REJECT_UNAUTHORIZED=0、サーバー側でNODE_ENV="test"を適用する必要がある)

import { AuthorizationCode } from 'simple-oauth2';
import pkceChallenge from 'pkce-challenge';
import Fastify from 'fastify';

const { code_challenge, code_verifier } = pkceChallenge.default(128);

const host = 'https://misskey.local';

const client = new AuthorizationCode({
  client: {
    id: 'http://localhost:3000/',
  },
  auth: {
    tokenHost: host,
    tokenPath: '/oauth/token',
    authorizePath: '/oauth/authorize',
  },
  options: {
    authorizationMethod: 'body',
  },
});

const redirect_uri = 'http://localhost:3000/redirect';

console.log('Open this URL in your browser:', client.authorizeURL({
  redirect_uri,
  scope: 'write:notes',
  state: 'state',
  code_challenge,
  code_challenge_method: 'S256',
}));

const fastify = Fastify();
let resolve;
let reject;
const promise = new Promise((res, rej) => {
  resolve = res;
  reject = rej;
});
fastify.get('/', async (request, reply) => {
  reply.send(`
<!DOCTYPE html>
<link rel='redirect_uri' href='/redirect'>
<div class='h-app'><a href='/' class='p-name'>Misklient
  `)
});
fastify.get('/redirect', async (request, reply) => {
  if (request.query.error) {
    reject(request.query.error);
    return;
  }
  if (!request.query.code) {
    reject('??');
    return;
  }
  resolve(request.query.code);
});
fastify.listen({ port: 3000, host: '0.0.0.0' });

const code = await promise;
await fastify.close();

const token = await client.getToken({
  code,
  redirect_uri,
  code_verifier,
});

const response = await fetch(new URL('api/notes/create', host), {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${token.token.access_token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    text: 'oauth works!'
  })
});

if (!response.ok) {
  console.error(await response.json());
  process.exit(1);
}
const id = (await response.json()).createdNote.id;
console.log('Successfully posted a note via OAuth!', new URL(`notes/${id}`, host).toString());

saschanaz and others added 2 commits July 22, 2023 14:07
* refactor(backend): use @types/oauth2orize-pkce

* Update package.json

* Update pnpm-lock.yaml

---------

Co-authored-by: Kagami Sascha Rosylight <saschanaz@outlook.com>
@syuilo
Copy link
Member

syuilo commented Jul 23, 2023

fastifyExpress って使ってる?

@saschanaz
Copy link
Member Author

fastifyExpress って使ってる?

oauth2orizeに必要でして使ってます

@syuilo syuilo merged commit eb7b5f9 into develop Jul 27, 2023
@syuilo syuilo deleted the oauth branch July 27, 2023 09:51
@syuilo
Copy link
Member

syuilo commented Jul 27, 2023

👍👍👍

EbiseLutica pushed a commit to shrimpia/misskey that referenced this pull request Jul 31, 2023
* feat(backend): support OAuth 2.0 authorization

* secureRndstr fix

* nanndekowareta

* nanndekowareta2

* nanndekowareta3

* unref?

* refactor to not close fastify

* use microformats-parser

* Update OAuth2ProviderService.ts

* clarify the reason behind dns lookup

* refactor(backend): use @types/oauth2orize-pkce (misskey-dev#11350)

* refactor(backend): use @types/oauth2orize-pkce

* Update package.json

* Update pnpm-lock.yaml

---------

Co-authored-by: Kagami Sascha Rosylight <saschanaz@outlook.com>

---------

Co-authored-by: mtgto <hogerappa@gmail.com>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

packages/backend:test packages/backend Server side specific issue/PR packages/frontend Client side specific issue/PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth2 Provider実装

5 participants