Đăng ký người dùng
Trong ví dụ này, chúng tôi sẽ trình bày cách đăng ký một người dùng mới bằng cách sử dụng API OneEntry.
✅ Mục đích của kịch bản:
- Chúng tôi lấy mẫu đăng ký để tạo mẫu frontend
- Người dùng nhập dữ liệu cần thiết và đăng ký.
- Sau khi đăng ký, người dùng nhận mã kích hoạt qua email/sms
- Người dùng nhập mã kích hoạt và kích hoạt người dùng đã tạo.
✅ Những gì bạn cần:
- Một PROJECT_URL và APP_TOKEN hợp lệ để xác thực với API OneEntry.
- Mẫu đăng ký với dấu hiệu "reg"
- Các trường mẫu (attributes) với các dấu hiệu "email_reg", "password_reg", "name_reg", "phone_reg"
- Email/số điện thoại hợp lệ để nhận mã kích hoạt
📌 Quan trọng:
- Những ví dụ này không bao gồm xử lý lỗi.
- Bạn có thể quản lý lỗi bằng cách sử dụng khối try-catch hoặc bằng cách sử dụng cấu trúc như await Promise.catch((error) => error).
📚 Xem trong tài liệu:
📦 Tham khảo SDK:
Thử nghiệm trực tiếp
Chạy phương thức này một cách tương tác trong JS SDK sandbox — kết nối URL Dự án và Mã ứng dụng của bạn khi truy cập lần đầu, sau đó mở:
- Đăng ký người dùng — Trong ví dụ này, chúng tôi trình bày cách đăng ký một người dùng mới bằng cách sử dụng API OneEntry.
Kịch bản
1. Nhập defineOneEntry từ SDK và định nghĩa PROJECT_URL và APP_TOKEN
Ví dụ:
import { defineOneEntry } from 'oneentry';
const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';
2. Tạo một khách hàng API với defineOneEntry()
Ví dụ:
const { AuthProvider, Forms } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});
3. Chúng tôi lấy một mẫu đăng ký để tạo một mẫu frontend Forms.getFormByMarker()
Ví dụ:
// Pre-filled credentials
const emailReg = 'your-email';
const passwordReg = 'your-password';
const nameReg = 'your-name';
useEffect(() => {
Forms.getFormByMarker('reg').then((data: any) => {
setForm(data);
const initial: Record<string, string> = {};
data?.attributes?.forEach((a: any) => {
// Pre-fill the login and name fields so the example is runnable out of the box
initial[a.marker] =
a.marker === 'email_reg'
? emailReg
: a.marker === 'password_reg'
? passwordReg
: a.marker === 'name_reg'
? nameReg
: '';
});
setValues(initial);
console.log('Form Entity ', data);
}).catch(console.error);
}, []);
Kết quả:
{
"id": 4,
"attributeSetId": 5,
"type": "sing_in_up",
"localizeInfos": {
"title": "Registration",
"titleForSite": "",
"successMessage": "",
"unsuccessMessage": "",
"urlAddress": "",
"database": "0",
"script": "0"
},
"version": 0,
"position": 1,
"identifier": "reg",
"processingType": "script",
"templateId": null,
"attributes": [
{
"type": "string",
"marker": "email_reg",
"isLogin": true,
"isSignUp": false,
"position": 1,
"settings": {},
"isVisible": true,
"isPassword": false,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
},
"emailInspectionValidator": true
},
"initialValue": null,
"localizeInfos": {
"title": "E-mail"
},
"additionalFields": {},
"isSignUpRequired": false,
"isNotificationEmail": false,
"isNotificationPhoneSMS": false,
"isNotificationPhonePush": false
},
{
"type": "string",
"marker": "name_reg",
"isLogin": false,
"isSignUp": true,
"position": 2,
"settings": {},
"isVisible": true,
"isPassword": false,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"initialValue": null,
"localizeInfos": {
"title": "Name"
},
"additionalFields": {},
"isSignUpRequired": false,
"isNotificationEmail": false,
"isNotificationPhoneSMS": false,
"isNotificationPhonePush": false
},
{
"type": "string",
"marker": "phone_reg",
"isLogin": false,
"isSignUp": true,
"position": 3,
"settings": {},
"isVisible": true,
"isPassword": false,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"initialValue": null,
"localizeInfos": {
"title": "Phone"
},
"additionalFields": {},
"isSignUpRequired": false,
"isNotificationEmail": false,
"isNotificationPhoneSMS": false,
"isNotificationPhonePush": false
},
{
"type": "string",
"marker": "password_reg",
"isLogin": false,
"isSignUp": false,
"position": 4,
"settings": {},
"isVisible": true,
"isPassword": true,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
},
"stringInspectionValidator": {
"stringMax": 0,
"stringMin": 0,
"stringLength": 0
}
},
"initialValue": null,
"localizeInfos": {
"title": "Password"
},
"additionalFields": {},
"isSignUpRequired": false,
"isNotificationEmail": false,
"isNotificationPhoneSMS": false,
"isNotificationPhonePush": false
},
{
"type": "string",
"marker": "email_notification_reg",
"isLogin": false,
"isSignUp": false,
"position": 5,
"settings": {},
"isVisible": true,
"isPassword": false,
"listTitles": [],
"validators": {},
"initialValue": null,
"localizeInfos": {
"title": "email for notification"
},
"additionalFields": {},
"isSignUpRequired": false,
"isNotificationEmail": true,
"isNotificationPhoneSMS": false,
"isNotificationPhonePush": false
}
],
"total": "1",
"moduleFormConfigs": []
}
4. Chuẩn bị dữ liệu cho việc đăng ký người dùng
Ví dụ:
const authData = [
{ marker: 'email_reg', value: email },
{ marker: 'password_reg', value: password },
];
const formData = sortedFields
.filter((f: any) => !AUTH_MARKERS.includes(f.marker) && values[f.marker])
.map((f: any) => ({
marker: f.marker,
type: f.type,
value: prepareValue(f.type, values[f.marker] || ''),
}));
const registrationData = {
formIdentifier: 'reg',
authData,
formData,
notificationData: {
email,
phonePush: [],
phoneSMS: values['phone_reg'] || '',
},
};
5. Đăng ký người dùng với AuthProvider.signUp()
Ví dụ:
const newUser = (await AuthProvider.signUp(
'email',
registrationData as any,
).catch((err: any) => err)) as any;
Kết quả:
{
"identifier": "kvasssukr.net@gmail.com",
"isActive": true,
"formData": [
{
"marker": "name_reg",
"type": "string",
"value": "Ivan"
},
{
"marker": "phone_reg",
"type": "string",
"value": "+10000000000"
},
{
"marker": "email_notification_reg",
"type": "string",
"value": "test@example.com"
}
],
"notificationData": {
"email": "kvasssukr.net@gmail.com",
"phonePush": [],
"phoneSMS": "+10000000000"
},
"locale": "en_US",
"updatedDate": "2026-06-06T12:45:01.228Z",
"importId": null,
"deletedAt": null,
"attributeSetId": null,
"id": 40,
"createdDate": "2026-06-06T12:45:01.228Z",
"version": 0,
"isDeleted": false,
"state": {},
"rating": {},
"attributesSets": {}
}
6. Người dùng nhập mã kích hoạt → xác minh với AuthProvider.checkCode()
Ví dụ:
// const code = prompt('Enter verification code:') as string;
// const isCorrect = await AuthProvider.checkCode('email', email, '1', code).catch(
// (err: any) => err,
// );
6. 1 kích hoạt người dùng với AuthProvider.activateUser()
Ví dụ:
// if (isCorrect) {
// await AuthProvider.activateUser('email', email, code).catch((err: any) => err);
// }
7. Xác thực người dùng đã kích hoạt với AuthProvider.auth()
Ví dụ:
const authResponse = await AuthProvider.auth('email', { authData }).catch(
(err: any) => err,
);
Kết quả:
{
"userIdentifier": "kvasssukr.net@gmail.com",
"authProviderIdentifier": "email",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR...pZCI6MTYsImF1dGhQ"
"refreshToken": "1745494429101-...-2834edf8"
}
Ví dụ cuối cùng
import React from 'react';
// Note: React is a sandbox global — in your project use named imports from 'react'
const { useState, useEffect } = React;
// 1. Import defineOneEntry from SDK and define PROJECT_URL and APP_TOKEN
import { defineOneEntry } from 'oneentry';
const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';
// 2. Creating an API client with [defineOneEntry()](/docs/index/#Installation)
const { AuthProvider, Forms } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});
// Markers that authenticate the user — everything else is sent as form data
const AUTH_MARKERS = ['email_reg', 'password_reg'];
// Prepare value for API submission by field type
function prepareValue(type: string, value: string) {
if (type === 'text') return [{ plainValue: value }];
if (type === 'list' || type === 'radioButton') return [value];
return value;
}
// Choose a sensible input type for a registration field by its marker
function inputTypeFor(marker: string) {
if (marker.includes('password')) return 'password';
if (marker.includes('email')) return 'email';
if (marker.includes('phone')) return 'tel';
return 'text';
}
const RegisterUser = () => {
const [form, setForm] = useState<any>(null);
const [values, setValues] = useState<Record<string, string>>({});
const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle');
const [errorMsg, setErrorMsg] = useState('');
// 3. We get a registration form with [Forms.getFormByMarker()](/docs/forms/getFormByMarker) for generating a frontend form
// Pre-filled credentials
const emailReg = 'your-email';
const passwordReg = 'your-password';
const nameReg = 'your-name';
useEffect(() => {
Forms.getFormByMarker('reg').then((data: any) => {
setForm(data);
const initial: Record<string, string> = {};
data?.attributes?.forEach((a: any) => {
// Pre-fill the login and name fields so the example is runnable out of the box
initial[a.marker] =
a.marker === 'email_reg'
? emailReg
: a.marker === 'password_reg'
? passwordReg
: a.marker === 'name_reg'
? nameReg
: '';
});
setValues(initial);
console.log('Form Entity ', data);
}).catch(console.error);
}, []);
if (!form) return <div>Loading...</div>;
const sortedFields = [...(form.attributes || [])].sort(
(a: any, b: any) => a.position - b.position,
);
const handleSubmit = async (e: any) => {
e.preventDefault();
setStatus('loading');
setErrorMsg('');
const email = values['email_reg'] || emailReg;
const password = values['password_reg'] || passwordReg;
// 4. Preparing data for user registration
const authData = [
{ marker: 'email_reg', value: email },
{ marker: 'password_reg', value: password },
];
const formData = sortedFields
.filter((f: any) => !AUTH_MARKERS.includes(f.marker) && values[f.marker])
.map((f: any) => ({
marker: f.marker,
type: f.type,
value: prepareValue(f.type, values[f.marker] || ''),
}));
const registrationData = {
formIdentifier: 'reg',
authData,
formData,
notificationData: {
email,
phonePush: [],
phoneSMS: values['phone_reg'] || '',
},
};
// 5. Register the user with [AuthProvider.signUp()](/docs/auth-provider/signUp)
const newUser = (await AuthProvider.signUp(
'email',
registrationData as any,
).catch((err: any) => err)) as any;
if (newUser?.statusCode >= 400) {
setErrorMsg(newUser.message || 'Registration failed');
setStatus('error');
return;
}
// 6. User enters the activation code → verify with [AuthProvider.checkCode()](/docs/auth-provider/checkCode)
// const code = prompt('Enter verification code:') as string;
// const isCorrect = await AuthProvider.checkCode('email', email, '1', code).catch(
// (err: any) => err,
// );
// 6.1 activate user with [AuthProvider.activateUser()](/docs/category/authprovider)
// if (isCorrect) {
// await AuthProvider.activateUser('email', email, code).catch((err: any) => err);
// }
// 7. Authenticate the activated user with [AuthProvider.auth()](/docs/auth-provider/auth)
const authResponse = await AuthProvider.auth('email', { authData }).catch(
(err: any) => err,
);
console.log({ newUser, authResponse });
setStatus('success');
};
return (
<form onSubmit={handleSubmit}>
<h2>{form.localizeInfos?.title || 'Register'}</h2>
{sortedFields.map((field: any) => {
const label = field.localizeInfos?.title || field.marker;
const value = values[field.marker] || '';
const required = !!field.validators?.requiredValidator?.strict;
const placeholder = field.additionalFields?.placeholder?.value || '';
const onChange = (val: string) =>
setValues((prev) => ({ ...prev, [field.marker]: val }));
return (
<div key={field.marker}>
<label htmlFor={field.marker}>{label}</label>
<input
id={field.marker}
type={inputTypeFor(field.marker)}
value={value}
placeholder={placeholder}
required={required}
onChange={(e: { target: { value: string } }) => onChange(e.target.value)}
/>
</div>
);
})}
<button type="submit" disabled={status === 'loading'}>
{status === 'loading' ? 'Registering...' : 'Register'}
</button>
{status === 'error' && <p role="alert">{errorMsg}</p>}
{status === 'success' && (
<p role="status">User registered and authenticated!</p>
)}
</form>
);
};
export default RegisterUser;