Open a01sa01to opened 21 hours ago
[!important] この Issue はまだ書き途中です。 仕様変更の可能性があります。 完成するまで実装はしないことをおすすめします。
OAuth 2.0 において、リソース所有者 (Resource Owner; ユーザーのこと) がサービスに対して「この情報を与えてもいいですよ」という認可 (Authorization) を与えるエンドポイントが必要です。 OAuth 2.0 仕様では Authorization Endpoint と呼ばれています。 この Authorization Endpoint を作成しましょう。
/oauth/authorize
405 Method not allowed
GET ならクエリパラメータとして、 POST ならリクエストボディとして受け取る
response_type
client_id
redirect_uri
scope
state
上から順に行うことを想定しています
oauth_client
id
SELECT * FROM oauth_client WHERE id = ?
ここまででおかしいものがあれば、 400 Bad Request レスポンスを返す。 以下、 redirect_uri パラメータが存在していない場合、その値は DB に登録されている唯 1 つの Callback URL で上書きしたとして話を進める。
400 Bad Request
error=invalid_request
code
error=unsupported_response_type
^[\x21|\x23-\x5B|\x5D-\x7E]+(?:\x20+[\x21|\x23-\x5B|\x5D-\x7E]+)*$
error=invalid_scope
"\
oauth_scope
name
SELECT COUNT(*) FROM oauth_scope WHERE name IN ?
なお、パラメータに state が存在する場合、リダイレクト時に state=パラメータの値 も付与すること
state=パラメータの値
name, description, logo_url, owner_id
/oauth/callback
POST
hidden
time
auth_token
submit
authorized
1
0
デザインは後回しでよいです ヘッダには Cache-Control: no-store, Pragma: no-cache を指定する
Cache-Control: no-store
Pragma: no-cache
client_id, redirect_uri, state, scope, time を環境変数 PRIVKEY に格納されている秘密鍵でハッシュを取り、その値を token として使用する。 ハッシュは ECDSA P-512 にすると @saitamau-maximum/auth/internal のやつが使えるのでうれしいかも? (特に強制はしません)
PRIVKEY
@saitamau-maximum/auth/internal
ハッシュの取り方はこの 4 つの値を持っていればなんでもいいと思っていて、例えば
client_id: 値 redirect_uri: 値 state: 値 scope: 値 time: 値
という文字列をそのままハッシュ関数に入れるとか
OAuth 2.0 において、リソース所有者 (Resource Owner; ユーザーのこと) がサービスに対して「この情報を与えてもいいですよ」という認可 (Authorization) を与えるエンドポイントが必要です。 OAuth 2.0 仕様では Authorization Endpoint と呼ばれています。 この Authorization Endpoint を作成しましょう。
エンドポイントの場所・許可するメソッド
/oauth/authorize
405 Method not allowed
を返す)受け取るパラメータ
GET ならクエリパラメータとして、 POST ならリクエストボディとして受け取る
response_type
: Required. stringclient_id
: Required. stringredirect_uri
: Optional. stringscope
: Optional. stringstate
: Optional. stringチェックすること
上から順に行うことを想定しています
client_id
が存在するかチェックし、またパラメータ内に複数存在しないこともチェックする。client_id
の値が DB の中にあるかチェックするoauth_client
, key:id
でヒットするかチェックすればよい (SELECT * FROM oauth_client WHERE id = ?
)redirect_uri
がパラメータ内に複数存在しないかチェックする (存在しなくてもよい)redirect_uri
が存在するかチェックするclient_id
の Callback URL として登録されているものか DB でチェックするclient_id
の Callback URL が 1 つだけ登録されているかチェックするここまででおかしいものがあれば、
400 Bad Request
レスポンスを返す。 以下、redirect_uri
パラメータが存在していない場合、その値は DB に登録されている唯 1 つの Callback URL で上書きしたとして話を進める。response_type
が存在するかチェックする。同じパラメータが複数存在しないことをチェックする。redirect_uri
のクエリパラメータにerror=invalid_request
を付与してリダイレクトさせるresponse_type
の値がcode
かチェックする。code
でない場合、error=unsupported_response_type
としてリダイレクトscope
が存在するかチェックする。^[\x21|\x23-\x5B|\x5D-\x7E]+(?:\x20+[\x21|\x23-\x5B|\x5D-\x7E]+)*$
の正規表現にマッチするか確認するerror=invalid_scope
でリダイレクトscope
は空白区切りの ASCII 印字可能文字 (ただし"\
の 2 つは除く) となっているはずscope
のすべてが scope として定義されている (=oauth_scope
内のname
として存在するか) チェックするSELECT COUNT(*) FROM oauth_scope WHERE name IN ?
が個数と一致するか確認したりすればいいのかなerror=invalid_scope
なお、パラメータに
state
が存在する場合、リダイレクト時にstate=パラメータの値
も付与すること応答
oauth_client
の Columnname, description, logo_url, owner_id
を使う/oauth/callback
, method:POST
hidden
, name=client_id
, value=パラメータのそのままの値hidden
, name=redirect_uri
, value=パラメータそのままの値hidden
, name=state
, value=パラメータそのままの値hidden
, name=scope
, value=パラメータそのままの値hidden
, name=time
, value=リクエストが来たときの時間 (UNIX ms)hidden
, name=auth_token
, value=下記参照submit
, name=authorized
, value=1
, 表示させる値=「承認」的な何かsubmit
, name=authorized
, value=0
, 表示させる値=「拒否」的な何かデザインは後回しでよいです ヘッダには
Cache-Control: no-store
,Pragma: no-cache
を指定するauth_token
についてclient_id, redirect_uri, state, scope, time を環境変数
PRIVKEY
に格納されている秘密鍵でハッシュを取り、その値を token として使用する。 ハッシュは ECDSA P-512 にすると@saitamau-maximum/auth/internal
のやつが使えるのでうれしいかも? (特に強制はしません)ハッシュの取り方はこの 4 つの値を持っていればなんでもいいと思っていて、例えば
という文字列をそのままハッシュ関数に入れるとか