Urutan cara kerja refresh token dalam sistem otentikasi berbasis token
1. Pengguna Login
Pengguna melakukan login dengan memberikan kredensial (seperti username dan password) ke aplikasi klien.
2. Aplikasi Klien Mengirim Permintaan Login ke Server Otentikasi
Aplikasi klien mengirim permintaan login ke server otentikasi, biasanya ke endpoint tertentu (misalnya, /login atau /auth/token).
Permintaan:
POST /login
Content-Type: application/json
{
"username": "user",
"password": "password"
}
3. Server Otentikasi Memverifikasi Kredensial
Server otentikasi memverifikasi kredensial pengguna. Jika valid, server menghasilkan dua token:
- Access Token: Token ini memiliki masa berlaku yang pendek (misalnya, 1 jam).
- Refresh Token: Token ini memiliki masa berlaku yang lebih panjang (misalnya, beberapa hari atau minggu).
Respons:
{
"access_token": "ACCESS_TOKEN",
"expires_in": 3600, // 1 hour
"refresh_token": "REFRESH_TOKEN"
}
4. Aplikasi Klien Menyimpan Token
Aplikasi klien menyimpan access token dan refresh token. Access token digunakan untuk permintaan API yang memerlukan otentikasi.
5. Pengguna Membuat Permintaan ke API
Pengguna membuat permintaan ke API yang dilindungi dengan menyertakan access token dalam header permintaan.
Permintaan:
GET /protected-resource
Authorization: Bearer ACCESS_TOKEN
6. Server API Memverifikasi Access Token
Server API memverifikasi access token. Jika valid dan belum kedaluwarsa, server API memproses permintaan dan mengirimkan respons.
7. Access Token Kedaluwarsa
Jika access token kedaluwarsa, pengguna tidak bisa lagi mengakses sumber daya yang dilindungi. Aplikasi klien perlu mendapatkan access token baru.
8. Aplikasi Klien Menggunakan Refresh Token
Aplikasi klien mengirim permintaan ke server otentikasi untuk mendapatkan access token baru menggunakan refresh token.
Permintaan:
POST /token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=REFRESH_TOKEN&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
9. Server Otentikasi Memverifikasi Refresh Token
Server otentikasi memverifikasi refresh token. Jika valid, server mengeluarkan access token baru (dan kadang-kadang refresh token baru juga).
Respons:
{
"access_token": "NEW_ACCESS_TOKEN",
"expires_in": 3600, // 1 hour
"refresh_token": "NEW_REFRESH_TOKEN" // Optional
}
10. Aplikasi Klien Menyimpan Token Baru
Aplikasi klien menyimpan access token baru dan, jika ada, refresh token baru. Access token baru digunakan untuk permintaan API berikutnya.
11. Ulangi Proses
Proses ini diulangi setiap kali access token kedaluwarsa. Refresh token memungkinkan aplikasi klien untuk terus mendapatkan access token baru tanpa memaksa pengguna untuk login kembali.
Contoh Implementasi
Berikut adalah contoh sederhana implementasi dalam kode menggunakan Express.js untuk server otentikasi dan frontend aplikasi klien.
Backend Server (Express.js)
const express = require('express');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
const users = [{ username: 'user', password: 'password' }];
const refreshTokens = [];
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username && u.password === password);
if (user) {
const accessToken = jwt.sign({ username }, 'ACCESS_TOKEN_SECRET', { expiresIn: '1h' });
const refreshToken = jwt.sign({ username }, 'REFRESH_TOKEN_SECRET');
refreshTokens.push(refreshToken);
res.json({ accessToken, refreshToken });
} else {
res.sendStatus(401);
}
});
app.post('/token', (req, res) => {
const { refreshToken } = req.body;
if (!refreshToken || !refreshTokens.includes(refreshToken)) {
return res.sendStatus(403);
}
jwt.verify(refreshToken, 'REFRESH_TOKEN_SECRET', (err, user) => {
if (err) return res.sendStatus(403);
const accessToken = jwt.sign({ username: user.username }, 'ACCESS_TOKEN_SECRET', { expiresIn: '1h' });
res.json({ accessToken });
});
});
app.listen(3000);
Frontend Aplikasi
async function login(username, password) {
const response = await fetch('/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
});
const data = await response.json();
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
}
async function fetchWithToken(url, options) {
let accessToken = localStorage.getItem('accessToken');
let response = await fetch(url, {
...options,
headers: { ...options.headers, 'Authorization': `Bearer ${accessToken}` },
});
if (response.status === 401) {
// Access token kedaluwarsa, gunakan refresh token
const refreshToken = localStorage.getItem('refreshToken');
const tokenResponse = await fetch('/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refreshToken }),
});
if (tokenResponse.ok) {
const { accessToken: newAccessToken } = await tokenResponse.json();
localStorage.setItem('accessToken', newAccessToken);
// Ulangi permintaan dengan access token baru
response = await fetch(url, {
...options,
headers: { ...options.headers, 'Authorization': `Bearer ${newAccessToken}` },
});
} else {
// Handle refresh token invalid atau kedaluwarsa
// Misalnya, redirect ke halaman login
}
}
return response;
}
Dengan mengikuti urutan cara kerja ini, Anda dapat mengimplementasikan sistem otentikasi yang aman dan efisien menggunakan access token dan refresh token.