🦊

簡単にMisskeyの認証が出来るライブラリを作った話

2022/12/18に公開

こちらになります。

https://github.com/Comamoca/miauth.js

Denoとnpmのページです。(DenoとNode両対応しています)

https://deno.land/x/miauthjs

https://www.npmjs.com/package/miauth-js

開発の動機

最近Misskeyを使い始めて、なかなか居心地が良くて気に入ったので何か貢献出来ないかと思い作りました。

始めはVimのクライアントを作ろうと思ったのですが、公式のSDKに認証機能が実装されていないらしい(READMEに記述はあるけど内容が書かれていない)のと、仕様が分かりづらくAPIを使ったプログラムの開発の支障になっているのでは、と感じ自分で実装する事にしました。

ちなみにVimのクライアントに関してはAllianaab2m さんが既に開発しています。MiAuth.jsを採用して下さるらしいので楽しみです。

https://github.com/Allianaab2m/vimskey

Misskeyとは

公式サイトからの引用です。

Misskeyはフリーかつオープンなプロジェクトで、誰でも自由にMisskeyを使ったサーバー(インスタンスと呼ばれます)を作成できるため、既に様々なインスタンスがインターネット上に公開されています。

また重要な特徴として、MisskeyはActivityPubと呼ばれる分散通信プロトコルを実装しているので、どのインスタンスを選んでも他のインスタンスのユーザーとやりとりすることができます。

これが分散型と言われる所以で、単一の運営者によって単一のURLで公開されるような、Twitterなどの他サービスとは根本的に異なっています。

インスタンスによって主な話題のテーマやユーザー層、言語などは異なり、自分にあったインスタンスを探すのも楽しみのひとつです(もちろん自分のインスタンスを作るのも一興です)。

MiAuthとは

MiAuthとは、Misskeyの独自認証システムです。
以前はOAuthでしたが、独自の認証システムに変更されました。

公式のドキュメント

MiAuthの仕様

ここが詳しいです。

ざっくり説明すると、
まず認証用のURLにユーザーがアクセスし、そこにアクセスした後確認用のURLにPOSTでアクセスするとトークンが入ったJsonが入ってくる感じです。

MiAuth.jsについて

リポジトリに全部書いてあるので(日本語版のドキュメントも用意してあります)ここで説明することがあんまり無いのですが、サンプルコードについて簡単に説明します。

import { readLines } from "https://deno.land/std@0.101.0/io/mod.ts";
import { MiAuth, Permissions, UrlParam } from "https://deno.land/x/miauthjs@0.0.2/mod.ts";

// 認証するユーザーがいるインスタンスのアドレス
const origin = "https://misskey.io";

// 要求するするパーミッションを指定
const permission = [Permissions.AccountRead];

// URLの生成に使うUUID
const session = crypto.randomUUID();

// 認証についての情報を指定する
const param: UrlParam = {
  name: "MyApp",
  permission: permission,
};

// MiAuthオブジェクトを作成
const miauth = new MiAuth(origin, param, session);

// 表示されたURL にアクセスして認証します
console.log(miauth.authUrl());

// Enterが押されるまでまで処理を止める
console.log("☕ 認証が完了したらEnterを押してください。");
for await (const line of readLines(Deno.stdin)) {
  if (line == "") {
    break;
  }
}

// 認証が完了したら呼び出す
console.log(await miauth.getToken())

URLにアクセスするとこのような画面が表示されるので許可をクリックしたターミナルに戻ってEnterを押すとトークンが表示されます。

MiAuthオブジェクトを作成し、authUrl()で作成したURLで認証を行い、getToken()でトークンを取得する事だけ頭に入れておけば使えると思います。

権限を指定するPermissionsは、補完が効くよう頑張ったので前に権限の名前、後ろにReadWriteが付くことを把握しておけば大丈夫だと思います。権限についてはここに詳しく書いてあります。

コード中にsessionという文字が出てきますが、これは認証URLの生成に必要なURLでUUID v4が推奨されています。ただ、他のバージョンを使うこともできます。UUIDを生成するのが面倒な場合はquickAuth() というラッパーを用意しているのでこちらを使うのがオススメです。これ別にオプションにすれば良かったと記事を書きながら後悔してるので、近いうちにオプション化されるかもしれません。

実装した感想とか

今回初めてDenoとNode.jsのライブラリを作ってみました。
dntはDenoの抜群の開発体験で両対応しているライブラリを作れるのでめちゃくちゃオススメです。
ただ、内部でnpm importを用いたライブラリを使うことが出来ないので、その辺りは注意が必要です。(package.jsonが被るから...?)esm.shなどを用いる場合は問題なさそうです。

実はsessionの実装中、npmのUUIDライブラリを使ったせいでビルドが通らずかなり焦りました...(Denoの組み込みAPIに目的の関数があったので助かりました...)

今後はmiauth.jsを使ってオレオレMisskeyクライアントを作ってみたいなぁなんて考えてます。それではまた次の記事で。

GitHubで編集を提案

Discussion