Repositori ini merupakan contoh penggunaan service Single Sign-On Politeknik Negeri Jakarta untuk aplikasi web berbasis NodeJS.
- NodeJS versi 12.0.0 direkomendasikan, namun minimal versi 10.19.0 (lts/dubnium) dibutuhkan.
- Gunakan endpoint method
client_secret_basic
pada saat Anda mendaftarkan client didalam SSO PNJ
Untuk mendaftarkan aplikasi Anda, silahkan buat tiket di https://layanan.pnj.ac.id/
Kami menggunakan node-openid-client
untuk implementasi pada repositori ini, install dengan :
npm install openid-client
Anda dapat secara otomatis mendapatkan konfigurasi openid otomatis dari endpoint .well-known
yang dimiliki oleh sso pnj :
const { Issuer } = require('openid-client');
// Atau gunakan promise: Issuer.discover().then(cb => {});
const ssoPnj = await Issuer.discover('https://sso.pnj.ac.id:4444');
// buat instance client dari hasil discover
const client = new ssoPnj.Client({
// Gunakan credential yang telah anda dapatkan dari SSO PNJ
client_id: '000',
client_secret: '000',
// Callback uri harus dimasukkan didalam array
redirect_uris: ['https://your-service.com/callback'],
response_types: ['code']
});
Untuk menghasilkan url yang akan meredirect user kedalam sso pnj gunakan :
const { generators } = require('openid-client');
// Generate 32bit encoded state
// Simpan variabel ini kedalam cookies/session/tempat penyimpanan lainnya
// yang relatif aman dari XSRF (ex: httpOnly cookies)
// variabel ini akan dicek kembali ketika akan menukar authorization_code
// ke tokenSet untuk menghindari MITM/XSRF.
const state = generators.state(32);
// contoh penyimpanan didalam expressjs
req.session.oauth_state = state;
// Dapatkan url
const url = client.authorizationUrl({
scope: 'openid',
redirect_uri: ['https://your-service.com/callback'],
state: state,
code_challenge_method: 'S256',
response_type: ['code']
});
// Lalu redirect user kepada url tersebut
// contoh redirect didalam expressjs
res.redirect(url);
Saat user dialihkan kembali ke redirect_uri
, gunakan kode berikut untuk menukarkan authorization_code
dengan tokenSet
const params = client.callbackParams(req);
// State yang telah disimpan didalam cookies/sesssion tadi akan dicek disini
const tokenSet = await client.callback('https://your-service.com/callback', params, {state: req.session.oauth_state});
// Anda dapat menyimpan token ini kedalam persistent storage (ex: db) untuk dipakai kembali atau di refresh ketika sudah expired
// untuk project contoh ini, kita akan simpan didalam session saja.
req.session.token_set = tokenSet;
Untuk mengambil informasi openid user, gunakan kode berikut
// Ambil access token dari storage
const userinfo = await client.userinfo(req.session.token_set.access_token);
// tampilkan userinfo ke dalam json
res.json(userinfo);
Berikut merupakan contoh objek user yang akan diterima ketika parsing id_token
{
"address": "187 Justen Point Suite 090\nWest Shania, TX 99746-9546",
"aud": [
"a895f57b-561c-44b5-ab17-495272346318"
],
"auth_time": 1622287922,
"date_of_birth": "1979-03-14",
"department_and_level": [
{
"access_level": 99,
"access_level_name": "Admin",
"department": "Teknik Informatika dan Komputer",
"department_short_name": "TIK"
}
],
"email": "[email protected]",
"iat": 1622287930,
"ident": 80779, //NIP/NIM, bergantung dengan akses level
"iss": "http://localhost:4444/",
"name": "Prof. Ivory Ferry",
"rat": 1622287922,
"sub": "4"
}
Untuk menyimpan atau mencocokkan user ke dalam database internal Anda, kami sarankan gunakan value dari sub
, atau ident
, karena value tersebut unique dalam setiap user.
Untuk informasi implementasi lebih lanjut tentang OpenID didalam NodeJS silahkan membaca dokumentasi dari package openid-client
https://github.com/panva/node-openid-client
npm install
nodemon ./bin/www
email developer di [email protected]
atau submit issues didalam repositori ini.