Créer des modèles de script
Le script Créer implémente la fonction définie lors de la création d’un utilisateur. Nous recommandons de nommer cette fonction create
.
Ce script est facultatif. Si cette option est activée, lorsqu’un utilisateur s’inscrit via la connexion universelle ou est créé via Auth0 Dashboard ou Management API Auth0, Auth0 exécutera le script pour créer un enregistrement utilisateur correspondant dans la base de données externe.
Lorsqu’un utilisateur est créé dans Auth0, Auth0 appelle une série de scripts :
Obtenir utilisateur : vérifie que l’utilisateur n’existe pas déjà dans Auth0 ou dans la base de données externe.
Créer : permet de créer l’utilisateur de la base de données externe.
Connexion : vérifie que l’utilisateur a été créé avec succès.
Fonction Créer
La fonction Create
permet de :
envoyer les profil de l’utilisateur des données à l’API de la base de données externe.
renvoyer une erreur si la création de l’utilisateur échoue.
Définition
La fonction create
accepte deux paramètres et renvoie une fonction de callback
:
create(user, callback): function
Was this helpful?
Paramètre | Type | Description |
---|---|---|
user |
Objet | Contient les données de profil utilisateur tirées du processus de création de l’utilisateur. |
callback |
Fonction | Utilisée pour transmettre les données d’erreur dans le pipeline. |
Exemple
Voici un exemple fictif en JavaScript de la manière dont vous pourriez implémenter la fonction create
. Pour des exemples spécifiques à un langage, consultez Exemples de scripts spécifiques à un langage.
function create(user, callback) {
// Send user profile data to external database API
let hashedPassword = hash(user.password);
let options = {
url: "https://example.com/api/create",
body: {
email: user.email,
username: user.username,
password: hashedPassword
}
};
send(options, err => {
// Return error in callback if user already exists
if (err && err.id === "USER_ALREADY_EXISTS") {
return callback(new ValidationError("user_exists", "My custom error message."));
} else if (err) {
// Return error in callback if error occurred
return callback(new Error("My custom error message."));
}
// Return `null` value in callback if user creation operation succeeded
return callback(null);
});
}
Was this helpful?
Chiffrement
Chiffrez la valeur du mot de passe à l’aide d’une bibliothèque de chiffrement de hachage cryptographique telle que bcrypt
afin d’éviter toute fuite de données potentielle.
Exemple
bcrypt.hash(password, 10, function (err, hash) {
if (err) {
return callback(err);
} else {
// Return hashed password
}
});
Was this helpful?
Fonction de rappel
La fonction de callback
accepte un paramètre et renvoie une fonction.
Définition
callback(error): function
Was this helpful?
Paramètre | Type | Requis | Description |
---|---|---|---|
error |
Objet | Requis | Contient des données d’erreur. |
Retourne un succès
Si l’opération de création de l’utilisateur a réussi, renvoyez la fonction de callback
et passer une valeur null
comme paramètre error
paramètre.
Exemple
return callback(null);
Was this helpful?
Renvoyer une erreur
Si une erreur survient, renvoyez la fonction de rappel, et transmettez l’information pertinente concernant l’erreur au paramètre error
:
Objet de type ValidationError
L’objet de type erreur personnalisé ValidationError
vous permet de transmettre des données qui seront affichées dans vos Journaux du locataire.
Constructeur
Le constructeur ValidationError
accepte jusqu’à deux paramètres :
new ValidationError(errorCode[, message]): ValidationError
Was this helpful?
Paramètre | Description |
---|---|
errorCode |
(Requis) Chaîne. Indique le type d’erreur. |
message |
(Facultatif) Chaîne. Contient des informations sur l’erreur. |
Renvoie une erreur indiquant que l’utilisateur existe déjà
Si vous renvoyez une erreur avec la valeur user_exists
pour le paramètre errorCode
, Auth0 enregistrera un événement du journal du locataire fs
.
Exemple
return callback(new ValidationError("user_exists", "My custom error message."));
Was this helpful?
Champ Événement de journal des locataires | Valeur |
---|---|
Code | fs |
Événement | Échec d’inscription |
Description | My custom error message. |
Paramètre d’objet utilisateur
Le paramètre d’objet user
contient un ensemble prédéfini de propriétés provenant du processus de création de l’utilisateur :
Propriété | Description |
---|---|
client_id |
L’ID client de l’application Auth0 si l’utilisateur s’est inscrit par la connexion universelle, ou la clé API si l’utilisateur a été créé par l’Auth0 Dashboard ou par Management API. |
tenant |
Le nom du locataire Auth0. |
email |
L’adresse courriel de l’utilisateur. |
password |
Le mot de passe de l’utilisateur en texte brut. |
username |
Le nom d’utilisateur de l’utilisateur. Requis uniquement si le paramètre Nécessite le nom d’utilisateur est activé pour la connexion à la base de données personnalisée. |
connection |
Le nom de la connexion Auth0. |
user_metadata |
Contient les propriétés de l’objet user_metadata sur le profil Auth0 de l’utilisateur, si l’objet existe. |
app_metadata |
Contient les propriétés de l’objet app_metadata sur le profil Auth0 de l’utilisateur, si l’objet existe. |
Propriété du nom d’utilisateur
Si votre connexion à la base de données personnalisée a le paramètre Requires Username activé, alors les scripts Login et Get User doivent prendre en charge la propriété username
, vous devez donc la stocker dans votre base de données externe.
Métadonnées de l’utilisateur et de l’application
Les propriétés user_metadata
et app_metadata
n’ont pas besoin d’être stockées dans votre base de données externe. Auth0 stocke automatiquement ces valeurs dans le cadre de l’enregistrement de profil utilisateur créé en interne.
Champs d’inscription personnalisés
Si vous créez et utilisez des champs personnalisés pendant le processus d’inscription, ils seront inclus dans l’objet user
.
Exemple
{
client_id: "8tkMo6n1QkKOazqPcSQd8wU7LzXYibgK",
tenant: "{yourAuth0Tenant}",
email: "username@domain.com",
password: "mySuperSecretPassword123",
username: "username456",
user_metadata: {
"language": "en"
},
app_metadata: {
"plan": "full"
}
}
Was this helpful?
Exemples de scripts propres à une langue
Auth0 fournit des exemples de scripts à utiliser avec les langages/technologies ci-dessous :
Fournisseur d’appartenances ASP.NET (MVC3 – Fournisseurs universels)
Fournisseur d’appartenances ASP.NET (MVC4 – Appartenance simple)
JavaScript
function create(user, callback) {
// This script should create a user entry in your existing database. It will
// be executed when a user attempts to sign up, or when a user is created
// through the Auth0 Dashboard or Management API.
// When this script has finished executing, the Login script will be
// executed immediately afterwards, to verify that the user was created
// successfully.
//
// The user object will always contain the following properties:
// * email: the user's email
// * password: the password entered by the user, in plain text
// * tenant: the name of this Auth0 account
// * client_id: the client ID of the application where the user signed up, or
// API key if created through the Management API or Auth0 Dashboard
// * connection: the name of this database connection
//
// There are three ways this script can finish:
// 1. A user was successfully created
// callback(null);
// 2. This user already exists in your database
// callback(new ValidationError("user_exists", "my error message"));
// 3. Something went wrong while trying to reach your database
// callback(new Error("my error message"));
const msg = 'Please implement the Create script for this database connection ' +
'at https://manage.auth0.com/#/connections/database';
return callback(new Error(msg));
}
Was this helpful?
Fournisseur d’appartenances ASP.NET (MVC3 – Fournisseurs universels)
function create(user, callback) {
const crypto = require('crypto');
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,
// Required to retrieve userId needed for Membership entity creation
rowCollectionOnRequestCompletion: true
}
});
const applicationId = 'your-application-id-goes-here';
/**
* hashPassword
*
* This function creates a hashed version of the password to store in the database.
*
* @password {[string]} the password entered by the user
* @return {[string]} the hashed password
*/
function hashPassword(password, salt) {
// the default implementation uses HMACSHA256 and since Key length is 64
// and default salt is 16 bytes, Membership will fill the buffer repeating the salt
const key = Buffer.concat([salt, salt, salt, salt]);
const hmac = crypto.createHmac('sha256', key);
hmac.update(Buffer.from(password, 'ucs2'));
return hmac.digest('base64');
}
connection.on('debug', function(text) {
// if you have connection issues, uncomment this to get more detailed info
// console.log(text);
}).on('errorMessage', function(text) {
// this will show any errors when connecting to the SQL database or with the SQL statements
console.log(JSON.stringify(text));
});
connection.on('connect', function(err) {
if (err) {
return callback(err);
}
createMembershipUser(user, function(err, user) {
if (err) return callback(err); // this will return a 500
if (!user) return callback(); // this will return a 401
callback(null, user);
});
});
function createMembershipUser(user, callback) {
const userData = {
UserName: user.email,
ApplicationId: applicationId
};
const createUser =
'INSERT INTO Users (UserName, LastActivityDate, ApplicationId, UserId, IsAnonymous) ' +
'OUTPUT Inserted.UserId ' +
'VALUES (@UserName, GETDATE(), @ApplicationId, NEWID(), \'false\')';
const createUserQuery = new Request(createUser, function(err, rowCount, rows) {
if (err) return callback(err);
// No records added
if (rowCount === 0) return callback(null);
const userId = rows[0][0].value;
const salt = crypto.randomBytes(16);
const membershipData = {
ApplicationId: applicationId,
Email: user.email,
Password: hashPassword(user.password, salt),
PasswordSalt: salt.toString('base64'),
UserId: userId
};
const createMembership =
'INSERT INTO Memberships (ApplicationId, UserId, Password, PasswordFormat, ' +
'PasswordSalt, Email, isApproved, isLockedOut, CreateDate, LastLoginDate, ' +
'LastPasswordChangedDate, LastLockoutDate, FailedPasswordAttemptCount, ' +
'FailedPasswordAttemptWindowStart, FailedPasswordAnswerAttemptCount, ' +
'FailedPasswordAnswerAttemptWindowsStart) ' +
'VALUES ' +
'(@ApplicationId, @UserId, @Password, 1, @PasswordSalt, ' +
'@Email, \'false\', \'false\', GETDATE(), GETDATE(), GETDATE(), GETDATE(), 0, 0, 0, 0)';
const createMembershipQuery = new Request(createMembership, function(err, rowCount) {
if (err) return callback(err);
if (rowCount === 0) return callback(null);
callback(null, rowCount > 0);
});
createMembershipQuery.addParameter('ApplicationId', TYPES.VarChar, membershipData.ApplicationId);
createMembershipQuery.addParameter('Email', TYPES.VarChar, membershipData.Email);
createMembershipQuery.addParameter('Password', TYPES.VarChar, membershipData.Password);
createMembershipQuery.addParameter('PasswordSalt', TYPES.VarChar, membershipData.PasswordSalt);
createMembershipQuery.addParameter('UserId', TYPES.VarChar, membershipData.UserId);
connection.execSql(createMembershipQuery);
});
createUserQuery.addParameter('UserName', TYPES.VarChar, userData.UserName);
createUserQuery.addParameter('ApplicationId', TYPES.VarChar, userData.ApplicationId);
connection.execSql(createUserQuery);
}
}
Was this helpful?
Fournisseur d’appartenances ASP.NET (MVC4 – Appartenance simple)
function create(user, callback) {
const crypto = require('crypto');
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,
// Required to retrieve userId needed for Membership entity creation
rowCollectionOnRequestCompletion: true
}
});
/**
* hashPassword
*
* This function hashes a password using HMAC SHA256 algorithm.
*
* @password {[string]} password to be hased
* @salt {[string]} salt to be used in the hashing process
* @callback {[function]} callback to be called after hashing the password
*/
function hashPassword(password, salt, callback) {
const iterations = 1000;
const passwordHashLength = 32;
crypto.pbkdf2(password, salt, iterations, passwordHashLength, 'sha1', function (err, hashed) {
if (err) return callback(err);
const result = Buffer.concat([Buffer.from([0], 1), salt, Buffer.from(hashed, 'binary')]);
const resultBase64 = result.toString('base64');
callback(null, resultBase64);
});
}
connection.on('debug', function (text) {
// if you have connection issues, uncomment this to get more detailed info
// console.log(text);
}).on('errorMessage', function (text) {
// this will show any errors when connecting to the SQL database or with the SQL statements
console.log(JSON.stringify(text));
});
connection.on('connect', function (err) {
if (err) return callback(err);
const createUser =
'INSERT INTO UserProfile (UserName) ' +
'OUTPUT Inserted.UserId ' +
'VALUES (@UserName)';
const createUserQuery = new Request(createUser, function (err, rowCount, rows) {
if (err || rowCount === 0) return callback(err);
const userId = rows[0][0].value;
const salt = crypto.randomBytes(16);
const createMembership =
'INSERT INTO webpages_Membership ' +
'(UserId, CreateDate, IsConfirmed, PasswordFailuresSinceLastSuccess, Password, PasswordSalt) ' +
'VALUES ' +
'(@UserId, GETDATE(), \'false\', 0, @Password, \'\')';
const createMembershipQuery = new Request(createMembership, function (err, rowCount) {
if (err || rowCount === 0) return callback(err);
callback(null, rowCount > 0);
});
hashPassword(user.password, salt, function (err, hashedPassword) {
if (err) return callback(err);
createMembershipQuery.addParameter('Password', TYPES.VarChar, hashedPassword);
createMembershipQuery.addParameter('PasswordSalt', TYPES.VarChar, salt.toString('base64'));
createMembershipQuery.addParameter('UserId', TYPES.VarChar, userId);
connection.execSql(createMembershipQuery);
});
});
createUserQuery.addParameter('UserName', TYPES.VarChar, user.email);
connection.execSql(createUserQuery);
});
}
Was this helpful?
MongoDB
function create(user, callback) {
const bcrypt = require('bcrypt');
const MongoClient = require('mongodb@3.1.4').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: user.email }, function (err, withSameMail) {
if (err || withSameMail) {
client.close();
return callback(err || new Error('the user already exists'));
}
bcrypt.hash(user.password, 10, function (err, hash) {
if (err) {
client.close();
return callback(err);
}
user.password = hash;
users.insert(user, function (err, inserted) {
client.close();
if (err) return callback(err);
callback(null);
});
});
});
});
}
Was this helpful?
MySQL
function create(user, callback) {
const mysql = require('mysql');
const bcrypt = require('bcrypt');
const connection = mysql({
host: 'localhost',
user: 'me',
password: 'secret',
database: 'mydb'
});
connection.connect();
const query = 'INSERT INTO users SET ?';
bcrypt.hash(user.password, 10, function(err, hash) {
if (err) return callback(err);
const insert = {
password: hash,
email: user.email
};
connection.query(query, insert, function(err, results) {
if (err) return callback(err);
if (results.length === 0) return callback();
callback(null);
});
});
}
Was this helpful?
PostgreSQL
function create(user, callback) {
//this example uses the "pg" library
//more info here: https://github.com/brianc/node-postgres
const bcrypt = require('bcrypt');
const postgres = require('pg');
const conString = 'postgres://user:pass@localhost/mydb';
postgres.connect(conString, function (err, client, done) {
if (err) return callback(err);
bcrypt.hash(user.password, 10, function (err, hashedPassword) {
if (err) return callback(err);
const query = 'INSERT INTO users(email, password) VALUES ($1, $2)';
client.query(query, [user.email, hashedPassword], function (err, result) {
// NOTE: always call `done()` here to close
// the connection to the database
done();
return callback(err);
});
});
});
}
Was this helpful?
SQL Server
function create(user, callback) {
//this example uses the "tedious" library
//more info here: http://pekim.github.io/tedious/index.html
const bcrypt = require('bcrypt');
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 = 'INSERT INTO dbo.Users SET Email = @Email, Password = @Password';
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, rows) {
if (err) return callback(err);
callback(null);
});
bcrypt.hash(user.password, 10, function(err, hash) {
if (err) return callback(err);
request.addParameter('Email', TYPES.VarChar, user.email);
request.addParameter('Password', TYPES.VarChar, hash);
connection.execSql(request);
});
});
}
Was this helpful?
Base de données SQL de Windows Azure
function create (user, callback) {
//this example uses the "tedious" library
//more info here: http://pekim.github.io/tedious/index.html
var Connection = require('tedious@1.11.0').Connection;
var Request = require('tedious@1.11.0').Request;
var TYPES = require('tedious@1.11.0').TYPES;
var bcrypt = require('bcrypt');
var connection = new Connection({
userName: 'your-user@your-server-id.database.windows.net',
password: 'the-password',
server: 'your-server-id.database.windows.net',
options: {
database: 'mydb',
encrypt: true
}
});
var query = "INSERT INTO users (Email, Password) VALUES (@Email, @Password)";
connection.on('debug', function(text) {
// Uncomment next line in order to enable debugging messages
// console.log(text);
}).on('errorMessage', function(text) {
console.log(JSON.stringify(text, null, 2));
}).on('infoMessage', function(text) {
// Uncomment next line in order to enable information messages
// console.log(JSON.stringify(text, null, 2));
});
connection.on('connect', function (err) {
if (err) { return callback(err); }
var request = new Request(query, function (err, rows) {
if (err) { return callback(err); }
console.log('rows: ' + rows);
callback(null);
});
bcrypt.hash(user.password, 10, function (err, hashedPassword) {
if (err) { return callback(err); }
request.addParameter('Email', TYPES.VarChar, user.email);
request.addParameter('Password', TYPES.VarChar, hashedPassword);
connection.execSql(request);
});
});
}
Was this helpful?
Demande avec Basic Auth
function create(user, callback) {
const request = require('request');
request.post({
url: 'https://myserviceurl.com/users',
json: user
//for more options check:
//https://github.com/mikeal/request#requestoptions-callback
}, function(err, response, body) {
if (err) return callback(err);
callback(null);
});
}
Was this helpful?
Dépanner
Si vous ne parvenez pas à créer un utilisateur dans votre base de données héritée ou dans Auth0 :
Vérifiez les instructions
console.log()
avec l’extension des journaux WebTask en temps réel d’Auth0.Recherchez l’utilisateur dans votre base de données héritée et supprimez-le. Si l’état utilisateur partiel est dans Auth0, utilisez les points de terminaison Supprimer un utilisateur ou Supprimer un utilisateur de connexion du Management API.
Assurez-vous que le Mode d’importation est désactivé, puis configurez le script de création.