Authentication
Authenticate using OAuth2/OIDC. End-users sign in and signup through Interactions and Signup apis. Clients obtain tokens via Authorization Code + PKCE and renew sessions with a refresh token.
Signup Process
Signup process include the following steps:
Signup a user
Register a new user and send validation email to his identifier.
Required attributes
- Name
first_name- Type
- string
- Description
User first name for signup.
- Name
channel- Type
- string
- Description
Verification channel, either
EMAILorPHONE_NUMBER.
- Name
identifier- Type
- string
- Description
Channel value as the the enum type.
Optional attributes
- Name
last_name- Type
- string | null
- Description
User optional last name for signup.
- Name
date_of_birth- Type
- Date | null
- Description
User optional data of birth for signup.
Request
curl -X POST https://api.account.raha.af/v1/auth/singup \
-H "Content-Type: application/json" \
-d '{
"first_name": "Ramez",
"last_name": "Rayyan",
"date_of_birth": "2000-02-02",
"channel": "EMAIL",
"identifier": "hojjatjanjan@gmail.com"
}'
Response
{
"user_id": "cdedc4f4-a61e-4a47-a070-6bc436964cbc",
"status": "PENDING_EMAIL_VERIFICATION",
"next": {
"email_verification": {
"sent": true,
"resend_after_seconds": 60
}
}
}
Verify Email
Verify the User email by entering the otp that sent to the Email.
Required attributes
- Name
channel- Type
- string
- Description
Verification channel, either
EMAIL.
- Name
identifier- Type
- string
- Description
Channel value as the the enum type.
- Name
otp- Type
- string
- Description
OTP that sent to the Email.
Request
curl -X POST https://api.account.raha.af/v1/auth/verify/email \
-H "Content-Type: application/json" \
-d '{
"channel": "EMAIL",
"identifier": "zora.tech64@gmail.com",
"otp": "1234"
}'
Response
{
"is_verified": true
}
Verify Phone number
Verify the User phone number by entering the otp that sent to the phone number.
Required attributes
- Name
channel- Type
- string
- Description
Verification channel,
PHONE_NUMBER.
- Name
identifier- Type
- string
- Description
Channel value as the the enum type.
- Name
otp- Type
- string
- Description
OTP that sent to the Phone number.
Request
curl -X POST https://api.account.raha.af/v1/auth/verify/email \
-H "Content-Type: application/json" \
-d '{
"channel": "PHONE_NUMBER",
"identifier": "+93786811941",
"otp": "728746"
}'
Response
{
"is_verified": true
}
Send Recovery Password OTP Code
Send Recovery password OTP code to a channel identifier.
Required attributes
- Name
channel- Type
- string
- Description
Verification channel, either
EMAILorPHONE_NUMBER.
- Name
identifier- Type
- string
- Description
Channel value as the the enum type.
Request
curl -X POST https://api.account.raha.af/v1/auth/recovery/code \
-H "Content-Type: application/json" \
-d '{
"channel": "EMAIL",
"identifier": "mohammadhojjat2024@gmail.com",
}'
Response
Empty
Verify Recovery OTP Code And Update Password
Verify Recovery password OTP code that sent to a channel identifier and update User Password.
Required attributes
- Name
channel- Type
- string
- Description
Verification channel, either
EMAILorPHONE_NUMBER.
- Name
identifier- Type
- string
- Description
Channel value as the the enum type.
- Name
otp_code- Type
- string
- Description
OTP code that send to the channel identifier by "auth/recovery/code" API.
- Name
password- Type
- string
- Description
New Updated Password for the User.
Request
curl -X PATCH https://api.account.raha.af/v1/auth/recovery/password \
-H "Content-Type: application/json" \
-d '{
"channel": "EMAIL",
"identifier": "mohammadhojjat2024@gmail.com",
"otp_code": "BGKWPQ",
"password":"saldjf3424",
} '
Response
Empty
Signin Prerequisites
- Register a client with
client_id,redirect_uri, and allowed origins. - Use PKCE
S256, and always sendstateandnonce. - Request only the scopes you need (e.g., openid profile email offline_access).
1) Start authorization
Build the authorize URL and redirect the user.
// Build the /oauth2/authorize URL with PKCE + state/nonce
const authBase = 'https://account.af/oauth2/authorize';
const params = new URLSearchParams({
client_id: 'YOUR_CLIENT_ID',
redirect_uri: 'https://app.example.com/callback',
response_type: 'code',
scope: 'openid profile email',
state: crypto.randomUUID(),
nonce: crypto.randomUUID(),
code_challenge: 'BASE64URL_SHA256_OF_CODE_VERIFIER',
code_challenge_method: 'S256'
});
window.location.assign(`${authBase}?${params}`);
// reference the interaction start endpoint to the endpoint of the same documentation
2) Handle interaction
The Authorization server shall call the interaction start endpoint server side. Fetch the interaction details and render the login form.
# Get interaction context (start)
curl -s https://api.account.af/api/v1/oauth/interactions/start
# Log the user in for this interaction
curl -X POST https://auth.example.com/api/v1/interactions/ixn_123/login \
-H "Content-Type: application/json" \
-d '{"identifier_type": "EMAIL", "identifier":"jane@example.com","password":"correcthorsebatterystaple"}'
3) Handle Select Profile
If a User has more than one profile Next step is select profile and Multi profile User should choose Profile that he want to login. Fetch the interaction details and render the login form.
# Post Select Profile context
curl -s https://api.account.af/api/v1/oauth/interactions/06f38970-f732-4771-9329-68006b878b47/select-profile
# Log the user in for this interaction
curl -X POST https://auth.example.com/api/v1/interactions/06f38970-f732-4771-9329-68006b878b47/select-profile \
-H "Content-Type: application/json" \
-d '{"pin": "soiwu309432mfc","profile_id": "06f38970-f735-4771-9321-68006b878b48"}'
4) Exchange code for tokens
The user is redirected back to your app with code and state. Validate state and exchange the code for tokens using the original code_verifier.
Exchange the code for tokens using the original code_verifier.
curl -X POST https://auth.example.com/api/v1/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&code=AUTH_CODE_HERE&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&code_verifier=YOUR_CODE_VERIFIER&client_id=YOUR_CLIENT_ID"
Security considerations
- Always use HTTPS to protect tokens in transit.
- Enforce PKCE S256, validate state and nonce.
- Session cookies are Secure, HttpOnly, and SameSite=Lax.
- Store tokens securely, never embed secrets in client code or VCS.