Get User スクリプトは、ユーザーが現在存在するかどうかを判定するために実行される関数を実装します。この関数の名前は getUser にすることを推奨します。
このスクリプトは、自動移行 では必須であり、レガシー認証では接続に設定されている操作に応じて条件付きで必須になります。重複するユーザーが作成されるのを防ぐため、返されるユーザープロファイルには永続的な user_id を設定することを Auth0 では推奨しています。
接続で自動移行が設定されていて、ユーザープロファイルがまだ作成されていない場合、このスクリプトは次の操作が発生するたびに実行されます。
メールアドレスの変更
サインアップ
パスワードリセット
接続でレガシー認証が設定されている場合、このスクリプトは次の操作が発生するたびに実行されます。
ユーザーの作成
メールアドレスの変更
パスワードの変更
パスワードリセット
getUser 関数では、次の処理を行う必要があります。
ユーザーの識別子を外部データベースの API に送信する。
ユーザーが見つかった場合は、そのプロファイルデータを返す。
ユーザーが存在するかどうかの判定中に問題が発生した場合は、エラーを返す。
getUser 関数は 2 つのパラメーターを受け取り、callback 関数を返します。
getUser ( email , callback ): function
パラメーター 型 説明 emailString ユーザーのメールアドレス。 callbackFunction エラーまたはプロファイルデータをパイプラインに渡すために使用します
これは、getUser 関数の実装方法を示す擬似 JavaScript の例です。言語ごとの例については、言語別のスクリプト例 を参照してください。
function getUser ( email , callback ) {
// ユーザー識別子を外部データベースAPIに送信する
let options = {
url: "https://example.com/api/search-users" ,
body: {
email: email
}
};
send ( options , ( err , profileData ) => {
// ユーザーの検索中に問題が発生した場合、コールバックでエラーを返す
if ( err ) {
return callback ( new Error ( "Could not determine if user exists or not." ));
} else {
// ユーザーが見つからなかった場合はコールバックでnullを返し、見つかった場合はプロファイルデータを返す
if ( ! profileData ) {
return callback ( null );
} else {
let profile = {
email: profileData . email ,
user_id: profileData . userId
};
return callback ( null , profile );
}
}
});
}
See all 28 lines
callback 関数は、ユーザープロファイルのデータまたはエラーデータをパイプライン内で受け渡すために使用されます。
callback 関数は最大2つのパラメーターを受け取り、関数を返します。
callback ( error [, profile ]): function
パラメーター 型 必須 説明 errorObject 必須 エラーデータを含みます。 profileObject 任意 ユーザーのプロフィールデータを含みます。
ユーザープロファイルを返す (ユーザーが見つかった場合)
ユーザーに対して Get User スクリプトが返すプロファイルデータは、Login スクリプトが返すプロファイルデータと一致している必要があります。
ユーザーが見つかった場合は、error パラメータに null を渡し、profile パラメータにユーザーのプロファイルデータを正規化形式 で渡します。標準フィールドに加えて、user_metadata、app_metadata、mfa_factors フィールドも含めることができます。
return callback ( null , {
username: "username" ,
user_id: "my-custom-db|username@domain.com" ,
email: "username@domain.com" ,
email_verified: false ,
user_metadata: {
language: "en"
},
app_metadata: {
plan: "full"
},
mfa_factors: [
{
phone: {
value: "+15551234567"
}
},
]
});
ユーザープロファイルを返さない (ユーザーが見つからない場合)
ユーザーが見つからない場合は、error パラメーターに null を渡し、profile パラメーターは省略します。
エラーが発生した場合は、何が原因で問題が起きたのかがわかる関連情報を含むエラーデータを error パラメーターに渡します。詳細については、カスタムデータベースのトラブルシューティング を参照してください。
return callback ( new Error ( "My custom error message." ));
Auth0 では、以下の言語/技術で使用できるサンプルスクリプトを提供しています。
function getByEmail ( email , callback ) {
// このスクリプトは、ユーザーを認証せずに既存のデータベースからユーザープロファイルを取得します。
// 認証を必要としないフロー(サインアップおよびパスワードリセット)を実行する前に、
// ユーザーが存在するかどうかを確認するために使用されます。
//
// このスクリプトの終了パターンは3通りあります:
// 1. ユーザーが正常に見つかった場合。プロファイルは以下の形式である必要があります:
// https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema
// callback(null, profile);
// 2. ユーザーが見つからなかった場合
// callback(null);
// 3. データベースへの接続中にエラーが発生した場合:
// callback(new Error("my error message"));
const msg = 'Please implement the Get User script for this database connection ' +
'at https://manage.auth0.com/#/connections/database' ;
return callback ( new Error ( msg ));
}
ASP.NET メンバーシップ プロバイダー (MVC3 - Universal Providers)
function getByEmail ( email , callback ) {
const sqlserver = require ( 'tedious@1.11.0' );
const Connection = sqlserver . Connection ;
const Request = sqlserver . Request ;
const TYPES = sqlserver . TYPES ;
const connection = new Connection ({
userName: 'the username' ,
password: 'the password' ,
server: 'the server' ,
options: {
database: 'the db name' ,
encrypt: true // for Windows Azure
}
});
connection . on ( 'debug' , function ( text ) {
// 接続に問題がある場合は、詳細情報を取得するためにコメントを解除してください
//console.log(text);
}). on ( 'errorMessage' , function ( text ) {
// SQLデータベースへの接続時またはSQLステートメントのエラーがここに表示されます
console . log ( JSON . stringify ( text ));
});
connection . on ( 'connect' , function ( err ) {
if ( err ) return callback ( err );
var user = {};
const query =
'SELECT Memberships.UserId, Email, Users.UserName ' +
'FROM Memberships INNER JOIN Users ' +
'ON Users.UserId = Memberships.UserId ' +
'WHERE Memberships.Email = @Username OR Users.UserName = @Username' ;
const getMembershipQuery = new Request ( query , function ( err , rowCount ) {
if ( err ) return callback ( err );
if ( rowCount < 1 ) return callback ();
callback ( null , user );
});
getMembershipQuery . addParameter ( 'Username' , TYPES . VarChar , email );
getMembershipQuery . on ( 'row' , function ( fields ) {
user = {
user_id: fields . UserId . value ,
nickname: fields . UserName . value ,
email: fields . Email . value
};
});
connection . execSql ( getMembershipQuery );
});
}
See all 45 lines
ASP.NET メンバーシップ プロバイダー (MVC4 - Simple Membership)
function getByEmail ( email , callback ) {
const sqlserver = require ( 'tedious@1.11.0' );
const Connection = sqlserver . Connection ;
const Request = sqlserver . Request ;
const TYPES = sqlserver . TYPES ;
const connection = new Connection ({
userName: 'the username' ,
password: 'the password' ,
server: 'the server' ,
options: {
database: 'the db name' ,
encrypt: true // Windows Azure の場合
}
});
connection . on ( 'debug' , function ( text ) {
// 接続に問題がある場合は、このコメントを解除するとより詳細な情報を確認できます
//console.log(text);
}). on ( 'errorMessage' , function ( text ) {
// SQL データベースへの接続時または SQL ステートメント実行時のエラーが表示されます
console . log ( JSON . stringify ( text ));
});
connection . on ( 'connect' , function ( err ) {
if ( err ) return callback ( err );
var user = {};
const query =
'SELECT webpages_Membership.UserId, UserName, UserProfile.UserName from webpages_Membership ' +
'INNER JOIN UserProfile ON UserProfile.UserId = webpages_Membership.UserId ' +
'WHERE UserProfile.UserName = @Username' ;
const getMembershipQuery = new Request ( query , function ( err , rowCount ) {
if ( err ) return callback ( err );
if ( rowCount < 1 ) return callback ();
callback ( null , user );
});
getMembershipQuery . addParameter ( 'Username' , TYPES . VarChar , email );
getMembershipQuery . on ( 'row' , function ( fields ) {
user = {
user_id: fields . UserId . value ,
nickname: fields . UserName . value ,
email: fields . UserName . value
};
});
connection . execSql ( getMembershipQuery );
});
}
See all 44 lines
function getByEmail ( email , callback ) {
const MongoClient = require ( 'mongodb@5.1.0' ). MongoClient ;
const client = new MongoClient ( 'mongodb://user:pass@mymongoserver.com' );
client . connect ( function ( err ) {
if ( err ) return callback ( err );
const db = client . db ( 'db-name' );
const users = db . collection ( 'users' );
users . findOne ({ email: email }, function ( err , user ) {
client . close ();
if ( err ) return callback ( err );
if ( ! user ) return callback ( null , null );
return callback ( null , {
user_id: user . _id . toString (),
nickname: user . nickname ,
email: user . email
});
});
});
}
function getByEmail ( email , callback ) {
const mysql = require ( 'mysql' );
const connection = mysql ({
host: 'localhost' ,
user: 'me' ,
password: 'secret' ,
database: 'mydb'
});
connection . connect ();
const query = 'SELECT id, nickname, email FROM users WHERE email = ?' ;
connection . query ( query , [ email ], function ( err , results ) {
if ( err || results . length === 0 ) return callback ( err || null );
const user = results [ 0 ];
callback ( null , {
user_id: user . id . toString (),
nickname: user . nickname ,
email: user . email
});
});
}
function loginByEmail ( email , callback ) {
//この例では "pg" ライブラリを使用しています
//詳細はこちら: https://github.com/brianc/node-postgres
const postgres = require ( 'pg' );
const conString = 'postgres://user:pass@localhost/mydb' ;
postgres . connect ( conString , function ( err , client , done ) {
if ( err ) return callback ( err );
const query = 'SELECT id, nickname, email FROM users WHERE email = $1' ;
client . query ( query , [ email ], function ( err , result ) {
// 注意: データベースへの接続を閉じるために
// 必ずここで `done()` を呼び出してください
done ();
if ( err || result . rows . length === 0 ) return callback ( err );
const user = result . rows [ 0 ];
return callback ( null , {
user_id: user . id ,
nickname: user . nickname ,
email: user . email
});
});
});
}
function getByEmail ( email , callback ) {
//この例では "tedious" ライブラリを使用しています
//詳細はこちら: http://pekim.github.io/tedious/index.html
const sqlserver = require ( 'tedious@1.11.0' );
const Connection = sqlserver . Connection ;
const Request = sqlserver . Request ;
const TYPES = sqlserver . TYPES ;
const connection = new Connection ({
userName: 'test' ,
password: 'test' ,
server: 'localhost' ,
options: {
database: 'mydb'
}
});
const query = 'SELECT Id, Nickname, Email FROM dbo.Users WHERE Email = @Email' ;
connection . on ( 'debug' , function ( text ) {
console . log ( text );
}). on ( 'errorMessage' , function ( text ) {
console . log ( JSON . stringify ( text , null , 2 ));
}). on ( 'infoMessage' , function ( text ) {
console . log ( JSON . stringify ( text , null , 2 ));
});
connection . on ( 'connect' , function ( err ) {
if ( err ) return callback ( err );
const request = new Request ( query , function ( err , rowCount , rows ) {
if ( err ) return callback ( err );
callback ( null , {
user_id: rows [ 0 ][ 0 ]. value ,
nickname: rows [ 0 ][ 1 ]. value ,
email: rows [ 0 ][ 2 ]. value
});
});
request . addParameter ( 'Email' , TYPES . VarChar , email );
connection . execSql ( request );
});
}
See all 37 lines
Windows Azure SQL Database
function getByEmail ( name , callback ) {
var profile = {
user_id: "103547991597142817347" ,
nickname: "johnfoo" ,
email: "johnfoo@gmail.com" ,
name: "John Foo" ,
given_name: "John" ,
family_name: "Foo"
};
callback ( null , profile );
}
async function getUserAsync ( email , callback ) {
//axiosの新バージョンが利用可能になり次第、更新すること (https://auth0-extensions.github.io/canirequire/#axios)
const axios = require ( "axios@0.22.0" );
let response ;
try {
response = await axios . post (
//SDLC環境を適切にサポートするため、APIのURLは接続設定に保存すること
configuration . baseAPIUrl + "/getUser" ,
//ユーザー資格情報をリクエストボディとして渡す
{
email: email ,
},
{
timeout: 10000 , //リクエストがタイムアウトした場合にスクリプトが必要なコールバックを実行できるよう、呼び出しを正常終了する
headers: {
//接続設定に保存されたapiKeyでAPIコールを保護する。
//手軽な方法だが、クライアントとAPI間でシークレットを共有すべきでないため、
// M2Mトークンを使用する方がより安全。
"x-api-key" : configuration . apiKey ,
},
}
);
} catch ( e ) {
if ( e . response . status === 404 ) {
//指定されたメールアドレス/usernameのユーザーが見つからない場合、APIが404を返すことを想定
return callback ( null , null );
}
//その他のエラーに対するコールバック
return callback ( new Error ( e . message ));
}
try {
let user = response . data ;
//テナントで複数のカスタムDB接続を使用する場合は、
//user_idに接続固有のキーをプレフィックスとして付加すること(例: "connName|" + user.user_id)
//これにより、すべてのDB接続でユーザーIDの一意性が保証される
return callback ( null , {
user_id: user . user_id ,
email: user . email ,
});
} catch ( e ) {
return callback ( new Error ( e . message ));
}
}
See all 47 lines
function getByEmail ( email , callback ) {
// {yourStormpathClientId} をあなたの Stormpath ID に置き換えてください
var url = 'https://api.stormpath.com/v1/applications/{yourStormpathClientId}/accounts' ;
// Stormpath API のクライアントID とシークレットを追加してください
var apiCredentials = {
user : '{yourStormpathApiId}' ,
password: '{yourStormpathApiSecret}'
};
// メールアドレスでユーザーを検索する GET リクエストを送信します
request ({
url: url ,
method: 'GET' ,
auth: apiCredentials ,
qs: { q: email },
json: true
}, function ( error , response , body ) {
if ( response . statusCode !== 200 ) return callback ();
var user = body . items [ 0 ];
if ( ! user ) return callback ();
var id = user . href . replace ( 'https://api.stormpath.com/v1/accounts/' , '' );
return callback ( null , {
user_id: id ,
username: user . username ,
email: user . email ,
email_verified: true
// Stormpath から引き継ぎたい追加フィールドをここに追加してください
});
});
}
See all 29 lines