LoginSignup
15
9

More than 3 years have passed since last update.

Auth0のManagement APIのアクセストークンを取得するメモ

Posted at

Auth0のManagement APIの利用時の話です。

前回の記事だとアクセストークンを直指定だったので、時間が立つとアクセストークンが切れてしまいます。

API経由で動的に生成する方法を調べたのでメモです。

アクセストークンのテスト

APIトークンを試す際には、公式のGet Access Tokens for Testing
にあるように、管理画面からAPIトークンを取得して直接指定すると良いです。

Auth0でログインユーザーのロール(Roles)を元にハンドリングするRulesを書いてみたの記事で書いてたやり方です。

アクセストークンを動的に生成する - プロダクション

公式のGet Access Tokens for Productionに載っているAPI(https://YOUR_DOMAIN/oauth/token)にリクエストしてAPIトークンを生成して利用できます。

公式サンプル

var options = {
  method: 'POST',
  url: 'https://YOUR_DOMAIN/oauth/token',
  headers: {'content-type': 'application/x-www-form-urlencoded'},
  form: {
    grant_type: 'client_credentials',
    client_id: 'YOUR_CLIENT_ID',
    client_secret: 'YOUR_CLIENT_SECRET',
    audience: 'https://YOUR_DOMAIN/api/v2/'
  }
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

これをRules内(Node.js)で書いていきます。

Rulesに適用する

Auth0でログインユーザーのロール(Roles)を元にハンドリングするRulesを書いてみたのスニペットと合わせるとこんな感じです。

util.promisifyでrequestをpromise化して、async/awaitで利用する形にしました。

async function (user, context, callback) {
  const util = require('util');
  const requestPromise = util.promisify(request);
  console.log(user);

  //1. メール確認
  if (!user.email || !user.email_verified) {
    return callback(new UnauthorizedError('Access denied.'));
  }
  //2-1. トークン生成
  const tokenApiOptions = {
    method: 'POST',
    url: `https://${configuration.domain}/oauth/token`,
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    form: {
      grant_type: 'client_credentials',
      client_id: configuration.client_id,
      client_secret: configuration.client_secret,
      audience: `https://${configuration.domain}/api/v2/`
    }
  };
  const tokenApiRes = await requestPromise(tokenApiOptions);
  const token = JSON.parse(tokenApiRes.body).access_token; //API経由で取得したトークン

  //2-2. ユーザーが所属するロールを取得
  const options = {
    url: `https://${configuration.domain}/api/v2/users/${user.user_id}/roles`,
    method: 'GET',
    headers: {
        'Authorization': `Bearer ${token}`
        },
    json: true,
  };
  const roleApiRes = await requestPromise(options);  

  //2-3. ロール判定
  const whiteList = ['role1','role2']; //許可するロール名
  const userRoles = roleApiRes.body.map(item => item.name);
  const userHasAccess = userRoles.some(value => whiteList.includes(value));

  if (!userHasAccess) {
    return callback(new UnauthorizedError('Access denied.'));
  }

  callback(null, user, context);
}

Settingsでconfigrationの値を設定すればOKです。

エラーなど

ClientIDとSecretについて

ちなみに、client_idclient_secretはテストでトークン作成した際のMACHINE TO MACHINEのものを利用したらうまく行きました。

通常のログインアプリケーションのclient idを利用すると以下のようなエラーが出てうまくいかなかったです。

"error":"unauthorized_client","error_description":"Grant type 'client_credentials' not allowed for the client."

Generate token in WebApi. Error: “Grant type ‘client_credentials’ not allowed for the client.”

function外だとUnexpected token const

function外には基本的に記述はしない方が良さそうです。

const util = require('util');
const requestPromise = util.promisify(request);

async function (user, context, callback) {
  
  
  
  省略
  
  
  
}
{
"code": 400,
"message": "Compilation failed: Unexpected token const",
"error": "Unexpected token const",
・
・
・
省略

これだとエラーはでなかったです。

async function (user, context, callback) {
   const util = require('util');
   const requestPromise = util.promisify(request);
  
  
  
  省略
  
  
  
}
15
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9