Misskey: アプリケーションを廃止

Created on 21 Dec 2019  ·  61Comments  ·  Source: syuilo/misskey

Summary

https://misskey.io/notes/7zfchyqpdt
https://misskey.io/notes/7zfczb7wh0

app/createでログインなしに誰もが大量にアプリケーションを作成できるようになった今、APIキー(i)の生成手順としてのアプリケーションのというのがあまり意味を成しておらず形骸化しており、アプリケーションを廃止してもいいのではないでしょうか。

新手順(案)

DBやマイグレーションのことはあまり考えていませんがそんなに難しくないはず

1. auth/session/create に今までapp/createに渡していたようなデータを渡す

{
// アプリの名前(今までどおりviaは表示したいので)
  name: "test",
// アプリの説明
  description: "my test application",
// アプリのパーミッション
  permission: ["write:notes"],
// コールバック
  callbackUrl: "https://my.app.tld/cb/misskey"
}

token(例: 798b9f6e-248d-43a7-a919-fabc664027f1)とurlが返ってくるのは現在と同様だが、新たにid(アクセスID(?), aid 例: 81jci5eqr0)が加わる。これをappSecretの代わりとする。

2. accessTokenを問い合わせる

ユーザーの認証が終わって{ callbackUrl }?token=798b...にアクセスされたらauth/session/userkeyにappIdとtokenを送信

{
  id: "81jci5eqr0",
  token: "798b9f6e-248d-43a7-a919-fabc664027f1"
}

accessTokenが返ってくるのは今までと同様。

3. APIキー(i)の生成

appSecretがidに変わっただけ

sha256(accessToken + id)
⚙️Server ✨Feature 💬Discussion 🧩API

Most helpful comment

なるほど
まあ既存のアプリ方式は互換性のために残すことは確実なんですけど、できればWebサービスでもスタンドアロンでも同じ(新しい)認証方式を使えるようにしたいというのもあります

All 61 comments

その都度生成がほぼ必須なクライアントアプリならそれでもいいかもしれないが、サーバー側で一回生成したアプリを使い回せるサードパーティーWebサービスへのログインだとアクセストークンが毎回生成されるのはだるそうな気がする

ユーザーが自由にアクセストークン的なものを発行できるようにして、それをアプリに入力させる方法はどうでしょう
アプリは入力されたアクセストークンを使ってAPIを利用できる

面倒くさそう

(それはそれとしてその機能は書き捨てスクリプトとかに便利そうなので別で欲しい)

アクセストークンが毎回生成される

今もそうなのでは...?(毎回というか一回の要求に対してだけど)

ユーザーが自由にアクセストークン的なものを発行

権限とかはアプリ側で指定する必要がありますし、そこまで思い切るのは厳しいかなと
ユーザーにしてみればボタンのクリックで完結したほうが簡単だし

ユーザーが自由にアクセストークン的なものを発行する方式でも、実装の仕方によっては今まで通りボタンのクリックのみで完結させることはできそう: 例えば

  1. アプリがMisskeyの指定の認証ページ(トークン発行要求ページ)を開かせる
  2. ユーザーがOKボタンみたいなのを押す
  3. トークンが発行されて、Misskeyサーバーから何らかの方法でイベントが伝えられアプリはそれを入手できる

とかどうかな

アクセストークンを保存しておけば、同じアプリ/Webサービスのアクセストークンが何個も生成されるということは無くなると思う

トークン発行ページがクエリ文字列とかを受け付けて、必要なら名前とかを変えてOKボタン押すだけみたいな感じ?

そうそう
権限もユーザーが必要なら編集することができるとか

支障はなさそうだけど、事情に詳しくないユーザーが変なふうに権限やコールバックURLを編集し、アプリ作者に動かないと文句を言うというのが想像できるので、最初は編集不可にしておいて変更するときは変更ボタンを押してからできるようにするみたいな画面にするのが望ましそう

アクセストークンを保存しておけば、同じアプリ/Webサービスのアクセストークンが何個も生成されるということは無くなると思う

アクセストークンを保存とは…?

Webサービスが自分のデータベースに保存するなど

ログインの時点では誰だかわからないのでアクセストークンわからなさそう

ふーむ

あー、Misskeyアカウント自体をアプリのログイン時の認証としている場合はアクセストークンを使い捨てることになるってことか

ログインの時点で誰だかわかるシステムを新たに作るとか?
そのシステムではあくまでも誰だかわかるだけで、アプリの認証とかはしない
認証はさっき言ったトークン発行方式を使うとか

個人的にはWebサービス用にアプリを残してスタンドアローンアプリ用の仕組みを別途作るのがよい気がする

なるほど
まあ既存のアプリ方式は互換性のために残すことは確実なんですけど、できればWebサービスでもスタンドアロンでも同じ(新しい)認証方式を使えるようにしたいというのもあります

いろいろ考えてもやはりアプリ形式が板な気がするし、アプリ形式を「アプリ」じゃなくて「使い回すと前回と同じアクセストークンがもらえる認証リクエスト」と思うといいのかもしれない

UI上(開発者センター)でアプリ作成できるようにする必要ってなさそうかな
分散型になった今、特定のインスタンスだけで使えるサードパーティアプリ作りたくなるケースって無さそうだし

互換性は残しつつも、「アプリ」という名称は変えた方が良さそうだなぁ

サードパーティーWebサービスへのログインだとアクセストークンが毎回生成されるのはだるそうな気がする

クライアントアプリでアクセストークンが毎回生成される時点で、Webサービスだけ特別扱いして使いまわせるようにする必要も特にないのかなと思えてきた

でも同じWebサイトにログインするたびにアプリ連携のところにWebサイト増えてったら嫌じゃない?

そもそもなんでクライアントアプリだとアクセストークン毎回生成しないといけないんだっけ

端末間でアプリのClientID/Secretを共有する方法がないから

なんとかしてアプリという仕組みを用いずとも同じ(Webサイト/クライアント)の連携が増えない方法を考えたい

というかあれだな、アプリという仕組みが無いと、Webサービスログインの際にどんどん連携が増えていくだけでなくいちいち「許可しますか?」というフォームを操作しなきゃいけなくなるのか

そうね

う~む

このIssueとは若干脱線するかもしれないけど、トークンに期限があっても良さそうに思った
一定期間そのトークンを使ってAPIリクエストが行われないと、もう使われてないと判断して削除する
そうすれば連携一覧で同じアプリがいっぱい表示されることが少なくなるのではないだろうか

悪くはないと思うけど、Androidとかデスクトップクライアントで何らかの理由でWebPushが利用できなくて通知のために通知APIへのポーリングとか走ってると端末が生きてる間は複数出そう

Webサービスって認証の際にコールバックURLを設定するよね?だからMisskey側で一度連携許可したWebサービス(コールバック)URLを「信頼済み」として記録しておいて、それ以降同じコールバックURLで認証リクエストされたら自動で許可するようにするのはどうだろう

それでトークンが使いまわせることになるのかは分からないけど、少なくとも毎回許可を確認されるのは回避できる

ドメインは期限切れなどにより他の人の手に渡ってしまう可能性があるので、あんまりよくなさそう

全然知らないWebサービスに、許可なく自分のアカウントIDだけでも分かってしまうのってプライバシー的に何か問題あるかな?

問題あるか

Webサービスで使いまわせない問題はいったん置いておいて、こんな方法考えたけどどうだろう
image

uuid重複したらどうなるのこれ

既に使われたUUIDはサーバーサイドで弾くことを予定

UUID自己申告よりサーバーにpermissionsとcallback送ってUUID返してそのUUIDでページに飛ばすみたいな仕組みのほうが便利そう (サーバーの対応/非対応判定もできるし)

あとcallback URLに直接tokenが飛んでくるの各所のアクセスログに残るのであまりよくなさそう

UUID自己申告よりサーバーにpermissionsとcallback送ってUUID返してそのUUIDでページに飛ばすみたいな仕組みのほうが便利そう

クライアントの実装の手間がひと手間増えないかな

あとcallback URLに直接tokenが飛んでくるの各所のアクセスログに残るのであまりよくなさそう

ほう この点は変えても良いかもしれない

tokenの代わりにUUIDを付けてリダイレクト?と思ったけどそれ実質token付けてるのと同じか

アクセスログについては気にしなくてもよい気がする

クライアントの実装の手間がひと手間増えないかな

MFMに比べたら5億倍マシ ページに飛ばす前に一回APIを叩かない方式だと、泥臭いバージョン取得&判定をしないとサーバー側で非対応インスタンスということに気づけないのと、自己申告だとUUID被った時にユーザーにエラー画面出るだけになっちゃうのUX低そう、というのを考えると (UUID自体の被る率はそんな高くないだろうけど、使ってるのが質のよくない乱数源とかだと被りやすくなるはずなので、なくはなさそう) 一回セッション作成APIみたいなのを叩かせたほうがよさそう

あとこれ名前とか指定できないけどただの付け忘れ? どこでどの端末で認証したかだけじゃどのサービスのトークンかわからなくなりそう

あとこれ名前とか指定できない

自己申告だからいくらでも偽装とか出来そうだし敢えて入れなかった

でも後から何が何だかわからなくならない?

何が何だかわかる必要ってあるかな

このアプリやっぱ気に食わないな〜権限取り上げてえ〜って時

とりあえず名前(とかアイコンとか)設定可能にするか

アクセスログについては気にしなくてもよい気がする

  1. トークンがそのまま残ると、サーバー側に残ったログから抽出しやすい (ログが流出してしまった時のことを考えると…)
  2. トークンをそのまま送ると、悪意のあるなしはさておきURLを外部に送るプロキシ/ブラウザ拡張機能とかに取られやすそう

ので、UUIDを返して、UUIDから取れるのは一回限り、みたいにしたほうがまだセキュアそう (本当はUUIDを返すついでにclient_secretも返してそれが必要になるほうがいいと思うけど、それもう現行のアプリケーションじゃん)

取れるのは一回限り

なるほど

というかもう現行のアプリケーションの名前変えるだけでいいのでは?実は

でも名前変えるにしろうまい名前思いつかないし、別に現状でいいのではって思う (/dev/でアプリ作れなくていいのは賛同するけど、v12で/dev/ごと消えたっぽいし)

どうせ現行のアプリ仕様だろうがトークン毎回発行にしようが結局ユーザーにトークン一覧を出してrevokeさせる以上は大量に(アプリ名)っていうトークンが並ぶのは変わらないし…

(それはそれとして、強いて言うならアプリorセッション作るときに端末名とかの認証したユーザーだけに見える付加情報を入れられるようにするといいかもしれない)

大量に(アプリ名)っていうトークンが並ぶのは変わらないし

アプリ作成の手間だったり、シークレットキーという概念だったり、セッション作成API叩く手間だったり、sha256する手間だったりを削れたらいいなというのもモチベーションのひとつではある

ふ〜む

シークレットキーはどうしようもなさそう
sha256は破壊的変更なしでなくす変更入れられそう

あとこの方法だと権限をユーザーが設定できるというのがある
「このアプリはxxとyyの権限を要求してるけど不安だからxxだけにしとこう」とか

やった

Was this page helpful?
0 / 5 - 0 ratings