Authentication คือ การพิสูจน์ตัวตนเพื่อความปลอดภัยในส่งข้อมูลระหว่าง Client กับ Server โดยเราสามารถดูตัวอย่างได้จาก postman ได้ง่ายและเร็วในการศึกษา หรือจะพูดได้ว่าเป็นหลักการ Reverse engineering ก็ได้มั่ง เพื่อที่จะทำเป็นมาตรฐานได้ดังนี้
No auth
ง่ายๆ สั้นๆ คือ ไม่การส่งข้อมูลที่ต้องพิสูจน์ตัวตนอะไรเลย สามารถใช้งานได้แบบสาธารณะ
API key
คือการส่งข้อมูลขออนุญาตเข้าใช้งาน Key และ Value ผ่าน Header หรือ Quuery Params เพื่อตรวจสิทธิ์ในการเข้าใช้งาน
Bearer token
เป็นการส่ง Token เพื่อตรวจสิทธิ์ในการเข้าใช้งาน โดยจะมี Prefix ของข้อมูลหน้า Token ที่ส่งไปใน Header ว่า Bearer
Basic auth
คือการส่งข้อมูล Username และ Password โดยข้อมูลจะถูก Encode เป็น base64 แล้วถูกส่งไปใน Header
const USERNAME = 'username';
const PASSWORD = 'password';
const authBasic = `Basic ${Buffer.from(USERNAME + ':' + PASSWORD).toString('base64')}`
console.log(authBasic);
//Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Digest auth
คือการตรวจสอบสิทธิ์การเข้าใช้งาน ด้วยวิธีการเข้ารหัสข้อมูลโดยใช้ Algorithm MD5 และ SHA ในการตรวจสอบความถูกต้องของข้อมูล โดยมีขั้นตอนที่ยุ่งยากดังนี้
ตัวอย่าง Algorithm MD5 โดยจะมีขั้นตอนดังนี้
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- username คือ สิ่งที่ใช้ในการระบุตัวตนผู้ใช้งาน
- password คือ สิ่งที่ใช้ในการพิสูจน์ตัวตนผู้ใช้งาน
- realm คือ string อะไรก็ได้ที่ระบุจาก Server
- method คือ รูปแบบของการส่งข้อมูลไปยัง Server เช่น GET, POST etc.
- uri คือ ข้อมูลที่ใช้ระบุตัวตนของทรัพยากร (resource) หรือ path ที่ใช้เข้าถึง resource
- nonce คือ unique string อะไรก็ได้ที่ระบุจาก Server
ข้อมูล Authentication ที่จะส่งไปกับ Header จะมีรูปแบบดังนี้
Digest username="username",
realm="test@mail.com",
nonce="",
uri="/test",
algorithm="MD5",
response="c62f1813b146be5382eba6861873c831"
สิ่งที่ต้องการคำนวณหาคือ response โดยมีวิธีคำนวณดังนี้
const crypto = require('crypto')
const username = 'username';
const password = 'password';
const realm = 'test@mail.com';
const method = 'GET';
const uri = '/test';
const nonce = '';
// function hashing MD5
const MD5 = (text) => {
let hash = crypto.createHash('md5');
//passing the data to be hashed
let data = hash.update(text, 'utf-8');
//Creating the hash in the required format
let gen_hash = data.digest('hex');
return gen_hash;
}
const HA1 = MD5(`${username}:${realm}:${password}`);
console.log(HA1);
// 63d45584ce377359e346690bde490668
const HA2 = MD5(`${method}:${uri}`);
console.log(HA2);
// e2b43a77e8b6707afcc1571382ca7c73
const response = MD5(`${HA1}:${nonce}:${HA2}`);
console.log(response);
// c62f1813b146be5382eba6861873c831
สามารถเปลี่ยน Algorithm เป็น MD5, SHA-256 และ SHA-512-256 แต่ขั้นตอนก็ยังเหมือนเดิม
📄digest-auth-md5.jsตัวอย่าง Algorithm MD5-sess โดยจะมีขั้นตอนดังนี้
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- username คือ สิ่งที่ใช้ในการระบุตัวตนผู้ใช้งาน
- password คือ สิ่งที่ใช้ในการพิสูจน์ตัวตนผู้ใช้งาน
- realm คือ string อะไรก็ได้ที่ระบุจาก Server
- method คือ รูปแบบของการส่งข้อมูลไปยัง Server เช่น GET, POST etc.
- uri คือ ข้อมูลที่ใช้ระบุตัวตนของทรัพยากร (resource) หรือ path ที่ใช้เข้าถึง resource
- nonce คือ unique string อะไรก็ได้ที่ระบุจาก Server
- cnonce คือ สิ่งที่ป้องกันการโจมตี ใหการเข้ารหัส
- nc คือ เลขฐานสิบหก ที่นับจำนวน Request ของ API
- qop คือ string ที่ระบุจาก Server
ข้อมูล Authentication ที่จะส่งไปกับ Header จะมีรูปแบบดังนี้
Digest username="username",
realm="test@mail.com",
nonce="",
uri="/test",
algorithm="MD5-sess",
qop=auth,
nc=12,
cnonce="0a4f113b",
response="49902a9875ea6b847ba59bc0162bc294",
opaque="7f40e41"
สิ่งที่ต้องการคำนวณหาคือ response โดยมีวิธีคำนวณดังนี้
const crypto = require('crypto')
const username = 'username';
const password = 'password';
const realm = 'test@mail.com';
const method = 'GET';
const uri = '/test';
const nonce = '';
const cnonce = '0a4f113b';
const nc = 12;
const qop = 'auth';
// function hasing MD5
const MD5 = (text) => {
let hash = crypto.createHash('md5');
//passing the data to be hashed
let data = hash.update(text, 'utf-8');
//Creating the hash in the required format
let gen_hash = data.digest('hex');
return gen_hash;
}
const HA1 = MD5(`${MD5(`${username}:${realm}:${password}`)}:${nonce}:${cnonce}`);
console.log(HA1);
// af6737a901699ef33e2186c3e8ff78b3
const HA2 = MD5(`${method}:${uri}`);
console.log(HA2);
// e2b43a77e8b6707afcc1571382ca7c73
const response = MD5(`${HA1}:${nonce}:${nc}:${cnonce}:${qop}:${HA2}`);
console.log(response);
// 49902a9875ea6b847ba59bc0162bc294
สามารถเปลี่ยน Algorithm เป็น MD5-sess, SHA-256-sess และ SHA-512-256-sess แต่ขั้นตอนก็ยังเหมือนเดิม
📄digest-auth-md5-sess.jsOAuth 1.0
ตัวอย่าง Signature ด้วย Algorithm HMAC-SHA1
ข้อมูล Authentication ที่จะส่งไปกับ Header จะมีรูปแบบดังนี้
OAuth oauth_consumer_key="RKCGzna7bv9YD57c",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1472121255",
oauth_nonce="e5VR16",
oauth_version="1.0",
oauth_signature="Or%2F2PqPg21wp967CASJtoo%2BF5Kk%3D"
วิธีการคำนวณหา oauth_signature ได้ดังนี้
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- Consumer Key
- Consumer Secret
- base_url
- method
- timestamp
- nonce
- parameters
const crypto = require('crypto')
const customerKey = "RKCGzna7bv9YD57c";
const customerSecret = encodeURIComponent("D+EdQ-gs$-%@2Nu7");
const base_url = "https://postman-echo.com/oauth1";
const method = "GET";
const timestamp = "1472121255";
const nonce = "e5VR16";
const parameters = {
oauth_consumer_key: customerKey,
oauth_signature_method: "HMAC-SHA1",
oauth_timestamp: timestamp,
oauth_nonce: encodeURIComponent(nonce),
oauth_version: "1.0"
}
// sort object by key
const oauth_parameter_string_object_ordered = {};
Object.keys(parameters).sort().forEach(function (key) {
oauth_parameter_string_object_ordered[key] = parameters[key];
});
// convert object into array
const oauth_parameter_string_array = [];
for (var key in oauth_parameter_string_object_ordered) {
oauth_parameter_string_array.push(`${key}=${oauth_parameter_string_object_ordered[key]}`);
}
// generate parameter string
const oauth_parameter_string = oauth_parameter_string_array.join('&');
const encodedUrl = encodeURIComponent(base_url);
const signature_base_string = `${method}&${encodedUrl}&${encodeURIComponent(oauth_parameter_string)}`
console.log(signature_base_string)
const signing_key = `${customerSecret}&`;
const oauth_signature = crypto.createHmac("sha1", signing_key).update(signature_base_string).digest('base64');
console.log(oauth_signature);
const encoded_oauth_signature = encodeURIComponent(oauth_signature);
console.log(encoded_oauth_signature);
สามารถเปลี่ยน Algorithm เป็น HMAC-SHA1, HMAC-SHA256, และ HMAC-SHA512 แค่วิธีการคำนวณก็ยังสามารถทำแบบเดิมได้
📄OAuth-1.0-HMAC-SHA1.jsตัวอย่าง Signature ด้วย Algorithm RSA-SHA1
ข้อมูล Authentication ที่จะส่งไปกับ Header จะมีรูปแบบดังนี้
OAuth oauth_consumer_key="RKCGzna7bv9YD57c",
oauth_signature_method="RSA-SHA1",
oauth_timestamp="1472121255",
oauth_nonce="e5VR16",
oauth_version="1.0",
oauth_signature="F9CBjycTpUgOOWk7hSLClpESVs9RB1gXrCrNdol%2FQsAmrL2HklZTJtRf51aahvpSeYtUJAYDunYiaYEGURB6k0HF82xkZ5kx2AgF%2B9xRuhMdYR55wNsik59Rm2mSpC%2FtceKZ7B3AHNHUto%2FTUn5jghZfdfENhjZEX0WQbQbSURg%3D"
วิธีการคำนวณหา oauth_signature ได้ดังนี้
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- Consumer Key
- Private Key
- base_url
- method
- timestamp
- nonce
- parameters
const crypto = require('crypto')
const customerKey = "RKCGzna7bv9YD57c";
const base_url = "https://postman-echo.com/oauth1";
const method = "GET";
const timestamp = "1472121255";
const nonce = "e5VR16";
const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC7vSldvzOQ8/wpaDOVaYaTYamFtNCz2pp9GIxsmVcPVALIo3iM
04+eQUyyx2mTZ4xtxLYiR0XV3+hIG7ftxtsz+FrGJKOsL4fUdPLFeoqCgjzVJ8wA
kVdKx8VStIlNdrhUko8f/ezh8JPP6Lpg5ISpbW/I7LAvtCGnmxVOOa2eRwIDAQAB
AoGAPkBMDiTPUXpFm+lMaXezQv14O7ioF2seHOrd7UivQIrn3WWvHGsuTRhz+Tf8
Pv9v5hn7FsSxWGjFWduvEm4E0tZCryKd3KcW4EyhY6e6eA/eW2Xka8ayFav6SkQB
BsT6NVbV6+hMpAew75s9288Snm0TPiWPWSTg9fertqv3RwECQQDjoE6POpVDDPp3
AZ2z1tVYObiRaAeqyMcF1xUboQbvnvgw0XVS8ZnE8jTBmbXWC0FxVyEyIBz6Kai9
e7yORsnHAkEA0yQG1G+KwtR140xkKUFZnQ3+XicqbI958Zg3nACLuc1cmuh6zS93
GYNu1TaFLu+d3zbzp+KQI1HVsovXP5aHgQJBANWLsAfI8vz7cQIyfuuXsYDabd/k
E8VSJPzCoifQcrxcjATojEPrKtJMU9gIx0FuP8//6MGoxOagLJDPQ77KhEMCQQCt
tgNEfiyc1K3U/wGdC54N3/h6QCDgRj7erQx7ddt/V10sOb7m13lWbVMfagazMgMi
JZTbeER8OpTlm7XRJCiBAkBK8pDtU63QQId2Bi89ShtXjw2L9imrdl8LAP6IlWNO
K8QYvI3WnOXZPHLzCLMV7SRbinTAxUlOhcg7vxVy5RKt
-----END RSA PRIVATE KEY-----`
const parameters = {
oauth_consumer_key: customerKey,
oauth_signature_method: "RSA-SHA1",
oauth_timestamp: timestamp,
oauth_nonce: encodeURIComponent(nonce),
oauth_version: "1.0"
}
// sort object by key
const oauth_parameter_string_object_ordered = {};
Object.keys(parameters).sort().forEach(function (key) {
oauth_parameter_string_object_ordered[key] = parameters[key];
});
// convert object into array
const oauth_parameter_string_array = [];
for (var key in oauth_parameter_string_object_ordered) {
oauth_parameter_string_array.push(`${key}=${oauth_parameter_string_object_ordered[key]}`);
}
// generate parameter string
const oauth_parameter_string = oauth_parameter_string_array.join('&');
const encodedUrl = encodeURIComponent(base_url);
const signature_base_string = `${method}&${encodedUrl}&${encodeURIComponent(oauth_parameter_string)}`
console.log(signature_base_string)
// GET&https%3A%2F%2Fpostman-echo.com%2Foauth1&oauth_consumer_key%3DRKCGzna7bv9YD57c%26oauth_nonce%3De5VR16%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1472121255%26oauth_version%3D1.0
const sign = crypto.createSign('SHA1');
sign.update(signature_base_string);
sign.end();
const oauth_signature = sign.sign(privateKey).toString('base64');
console.log(oauth_signature);
// F9CBjycTpUgOOWk7hSLClpESVs9RB1gXrCrNdol/QsAmrL2HklZTJtRf51aahvpSeYtUJAYDunYiaYEGURB6k0HF82xkZ5kx2AgF+9xRuhMdYR55wNsik59Rm2mSpC/tceKZ7B3AHNHUto/TUn5jghZfdfENhjZEX0WQbQbSURg=
const encoded_oauth_signature = encodeURIComponent(oauth_signature);
console.log(encoded_oauth_signature);
// F9CBjycTpUgOOWk7hSLClpESVs9RB1gXrCrNdol%2FQsAmrL2HklZTJtRf51aahvpSeYtUJAYDunYiaYEGURB6k0HF82xkZ5kx2AgF%2B9xRuhMdYR55wNsik59Rm2mSpC%2FtceKZ7B3AHNHUto%2FTUn5jghZfdfENhjZEX0WQbQbSURg%3D
สามารถเปลี่ยน Algorithm เป็น RSA-SHA1, RSA-SHA256, และ RSA-SHA512 แค่วิธีการคำนวณก็ยังสามารถทำแบบเดิมได้
📄OAuth-1.0-RSA-SHA1.jsตัวอย่าง Signature ด้วย Algorithm PLAINTEXT
ข้อมูล Authentication ที่จะส่งไปกับ Header จะมีรูปแบบดังนี้
OAuth oauth_consumer_key="RKCGzna7bv9YD57c",
oauth_signature_method="PLAINTEXT",
oauth_timestamp="1472121255",
oauth_nonce="e5VR16",
oauth_version="1.0",
oauth_signature="D%252BEdQ-gs%2524-%2525%25402Nu7%26key"
วิธีการคำนวณหา oauth_signature ได้ดังนี้
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- Customer Secret
- Token Secret
const customerSecret = encodeURIComponent("D+EdQ-gs$-%@2Nu7");
const tokenSecret = 'key'// optional
const signing_key = `${customerSecret}&${tokenSecret}`;
const oauth_signature = signing_key;
console.log(oauth_signature);
// D%2BEdQ-gs%24-%25%402Nu7&key
const encoded_oauth_signature = encodeURIComponent(oauth_signature);
console.log(encoded_oauth_signature);
// D%252BEdQ-gs%2524-%2525%25402Nu7%26key
📄OAuth-1.0-PLAINTEXT.jsOAuth 2.0
oauth2.0 โดยจะแบ่งเป็น Grant Type ได้ 4 ประเภทดังนี้
Authorization code
วิธีส่งข้อมูล Client Authentication จะแบ่งออกเป็น 2 แบบคือ
- Send as Basic Auth header
- Send client credentials in body
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- Callback URL
- Auth URL
- Access Token URL
- Client ID
- Client Secret
โดยจะมีขั้นตอนดังนี้
1. Client ขอสิทธิ์ในการเข้าใช้งาน โดยส่ง client_id และ redirect_uri ในรูปแบบ Query Params ไปกับ Auth URL ดังนี้
GET http://localhost:3000/api/v1/login/oauth/authorize?response_type=code&client_id=test-Client-ID&redirect_uri=https%3A%2F%2Foauth.pstmn.io%2Fv1%2Fcallback
2. โดยจะ redirect ไปยัง https://oauth.pstmn.io/v1/callback และส่ง code ไปด้วย ดังนี้
https://oauth.pstmn.io/v1/callback?code=5YIPSpuhW6ll3wcgY6iE7jPwGds=
3. จากนั้นจะส่งข้อมูลต่อไปใน API Access Token URL ดังนี้
- Send as Basic Auth header
โดยจะส่ง Client ID และ Client Secret ให้อยู่ในรูปแบบ Basic auth แล้วไปใน Header ด้วย Key Authorization
const client_id = 'test-Client-ID';
const client_secret = 'test-Client-Secret';
const authBasic = `Basic ${Buffer.from(client_id + ':' + client_secret).toString('base64')}`
console.log(authBasic);
//Basic dGVzdC1DbGllbnQtSUQ6dGVzdC1DbGllbnQtU2VjcmV0
และส่ง Grant Type, Code, Redirect URI และ Client Id ไปใน Body ด้วย Content Type application/x-www-form-urlencoded ดังนี้
{"grant_type":"authorization_code",
"code":"5YIPSpuhW6ll3wcgY6iE7jPwGds=",
"redirect_uri":"https://oauth.pstmn.io/v1/callback",
"client_id":"test-Client-ID"}
- Send client credentials in body
โดยจะส่ง Client ID, Client Secret, Grant Type, Code, Redirect URI ไปใน Body ด้วย Content Type application/x-www-form-urlencoded ดังนี้
{"grant_type":"authorization_code",
"code":"5YIPSpuhW6ll3wcgY6iE7jPwGds=",
"redirect_uri":"https://oauth.pstmn.io/v1/callback",
"client_id":"test-Client-ID",
"client_secret":"test-Client-Secret"}
4. หลังจากการตรวจสิทธิ์การใช้งานแล้วผ่านแล้ว Server จำเป็นต้องส่งอย่างน้อย access_token ให้กับผู้ใช้งาน ตัวอย่าง ดังนี้
{"access_token":"4VfcgzZGZMxAqS/nytLCmHF5qyM=",
"refresh_token":"1Ts5LuZB0zB90zteEq7tMzW7GpA=",
"token_type":"Bearer",
"expires_in":3600,
"scope":""}
Authorization code (with PKCE)
ขั้นตอนคล้ายๆ กับ Authorization code ปกติ แต่จะเพิ่ม Code Challenge Method เป็นแบบ SHA-256 หรือ Plain โดยจะขั้นตอนดังนี้
วิธี่ส่งข้อมูล Client Authentication จะแบ่งออกเป็น 2 แบบคือ
- Send as Basic Auth header
- Send client credentials in body
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- Callback URL
- Auth URL
- Access Token URL
- Client ID
- Client Secret
โดยจะมีขั้นตอนดังนี้
1. Client ขอสิทธิ์ในการเข้าใช้งาน โดยส่ง client_id, redirect_uri, code_challenge และ code_challenge_method ในรูปแบบ Query Params ไปกับ Auth URL ดังนี้
GET http://localhost:3000/api/v1/login/oauth/authorize?response_type=code&client_id=test-Client-ID&redirect_uri=https%3A%2F%2Foauth.pstmn.io%2Fv1%2Fcallback&code_challenge=J_-rkFDpSPSC7vS9Af9U4ka5FczY552BUgy9kR76JEo&code_challenge_method=S256
2. โดยจะ redirect ไปยัง https://oauth.pstmn.io/v1/callback และส่ง code ไปด้วย ดังนี้
https://oauth.pstmn.io/v1/callback?code=5YIPSpuhW6ll3wcgY6iE7jPwGds=
3. จากนั้นจะส่งข้อมูลต่อไปใน API Access Token URL ดังนี้
- Send as Basic Auth header
โดยจะส่ง Client ID และ Client Secret ให้อยู่ในรูปแบบ Basic auth แล้วไปใน Header ด้วย Key Authorization
const client_id = 'test-Client-ID';
const client_secret = 'test-Client-Secret';
const authBasic = `Basic ${Buffer.from(client_id + ':' + client_secret).toString('base64')}`
console.log(authBasic);
//Basic dGVzdC1DbGllbnQtSUQ6dGVzdC1DbGllbnQtU2VjcmV0
และส่ง Grant Type, Code, Redirect URI และ Client Id ไปใน Body ด้วย Content Type application/x-www-form-urlencoded ดังนี้
{"grant_type":"authorization_code",
"code":"J97MpZoQKSYoTIIvJSC7xbngAT8=",
"redirect_uri":"https://oauth.pstmn.io/v1/callback",
"code_verifier":"SgvbZcaHrO3jMYxBt27ePypc6Y83amb09Ao6JRrh9UE",
"client_id":"test-Client-ID"}
code_verifier จะถูกสร้างอัตโนมัติหากไม่มีการระบุเอาไว้
- Send client credentials in body
โดยจะส่ง Client ID, Client Secret, Grant Type, Code, Redirect URI และ Code verifier ไปใน Body ด้วย Content Type application/x-www-form-urlencoded ดังนี้
{"grant_type":"authorization_code",
"code":"dsso9aaR8b5ct1T45dg3GsKWWQU=",
"redirect_uri":"https://oauth.pstmn.io/v1/callback",
"code_verifier":"a6yv7V9qEgqS7TmaMZW1jNe-o6uREG8421tM1XBFgCA",
"client_id":"test-Client-ID",
"client_secret":"test-Client-Secret"}
code_verifier จะถูกสร้างอัตโนมัติหากไม่มีการระบุเอาไว้
4. หลังจากการตรวจสิทธิ์การใช้งานแล้วผ่านแล้ว Server จำเป็นต้องส่งอย่างน้อย access_token ให้กับผู้ใช้งาน ตัวอย่าง ดังนี้
{"access_token":"4VfcgzZGZMxAqS/nytLCmHF5qyM=",
"refresh_token":"1Ts5LuZB0zB90zteEq7tMzW7GpA=",
"token_type":"Bearer",
"expires_in":3600,
"scope":""}
Implicit
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- Callback URL
- Auth URL
- Client ID
โดยจะมีขั้นตอนดังนี้
1. Auth URL คือ API สำหรับตรวจสอบสิทธิ์และส่งรหัสเข้าใช้งานให้ผู้ใช้งาน
GET http://localhost:3000/login/oauth/authorize
โดยจะส่งข้อมูล Client ID และ Callback URL ในรูปแบบ Query Params ไปกับ Auth URL ดังนี้
http://localhost:3000/login/oauth/authorize?response_type=token&client_id=test-Client-ID&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fv1%2Fregistered%2Fcallback
2. เมื่อ Server ได้ข้อมูลสำหรับตรวจสอบสิทธิ์การใช้งานผ่านแล้ว ก็จะ redirect ไปยัง Callback URL โดยจะส่ง access_token ในรูปแบบ Query Params กลับไปด้วย
GET http://localhost:3000/api/v1/registered/callback?access_token=7ya+OsORA0+wy7Vcpqun0QPiw4E=
Password credentials
วิธี่ส่งข้อมูล Client Authentication จะแบ่งออกเป็น 2 แบบคือ
- Send as Basic Auth header
- Send client credentials in body
จำเป็นต้องมีข้อมูลที่ใช้ดังนี้
- Access Token URL
- Grant Type
- Client ID
- Client Secret
- Username
- Password
- Scope
ตัวอย่าง การใช้งาน Grant Type Password credentials ดังนี้
1. Access Token URL จำต้องมี API สำหรับตรวจสอบสิทธิ์และส่งรหัสเข้าใช้งานให้ผู้ใช้งาน ตัวอย่างดังนี้
POST http://localhost:3000/login/oauth/access_token
//ตามตัวอย่างไม่ได้ระบุว่าต้องเป็น Method POST ให้ allow all method ไว้ก่อนก็ได้นะ
2. ส่งข้อมูลเพิ่อทำการขอ access_token
- Send as Basic Auth header
โดยจะส่ง Client ID และ Client Secret ให้อยู่ในรูปแบบ Basic auth แล้วไปใน Header ด้วย Key Authorization
const client_id = 'test-Client-ID';
const client_secret = 'test-Client-Secret';
const authBasic = `Basic ${Buffer.from(client_id + ':' + client_secret).toString('base64')}`
console.log(authBasic);
//Basic dGVzdC1DbGllbnQtSUQ6dGVzdC1DbGllbnQtU2VjcmV0
และส่ง Grant Type, Username และ Password ไปใน Body ด้วย Content Type application/x-www-form-urlencoded ดังนี้
{"grant_type":"password",
"username":"Username",
"password":"Password"}
- Send client credentials in body
โดยจะส่ง Client ID, Client Secret, Grant Type, Username และ Password ไปใน Body ด้วย Content Type application/x-www-form-urlencoded ดังนี้
{"grant_type":"password",
"username":"Username",
"password":"Password",
"client_id":"test-Client-ID",
"client_secret":"test-Client-Secret"}
3. หลังจากการตรวจสิทธิ์การใช้งานแล้วผ่านแล้ว Server จำเป็นต้องส่งอย่างน้อย access_token ให้กับผู้ใช้งาน ตัวอย่าง ดังนี้
{"access_token":"4VfcgzZGZMxAqS/nytLCmHF5qyM=",
"refresh_token":"1Ts5LuZB0zB90zteEq7tMzW7GpA=",
"token_type":"Bearer",
"expires_in":3600,
"scope":""}
Client credentials
ขั้นตอนคล้ายๆ กับ Password credentials แต่จะไม่มีการส่ง Username และ Password และให้เปลี่ยน grant_type ตอนส่งข้อมูลไปตรวจสอบสิทธิ์การใช้งานจาก password เปลี่ยนเป็น client_credentials
Hawk authentication
ตัวอย่าง ข้อมูล Authentication ที่จะส่งไปกับ Header จะมีรูปแบบดังนี้
Hawk id="dh37fgj492je",
ts="1669301809",
nonce="RZKGNz",
mac="ETCKAQIzJsKGXJSaMzqpe00bsufrzB1g+8IS2Y9cPZM="
วิธีการคำนวณหาเลข mac โดยใช้ขั้นตอนดังนี้
const crypto = require('crypto')
const hawk_auth_id = 'dh37fgj492je';
const hawk_auth_key = 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn';
const method = 'GET';
const nonce = 'RZKGNz';
const timestamp = 1669301809;
//https://postman-echo.com/auth/hawk
const host = 'postman-echo.com';
const resource = '/auth/hawk';
const port = '443'; //example: 80,433
const ext = ''
// request string (newline terminated values):
const hawk_header = `hawk.1.header\n${timestamp}\n${nonce}\n${method}\n${resource}\n${host}\n${port}\n\n${ext}\n`
console.log(hawk_header)
ตัวอย่างข้อมูล header แบบขึ้นบรรทัดใหม่
hawk.1.header
1669301809
RZKGNz
GET
/auth/hawk
postman-echo.com
443
const hmac = crypto.createHmac('sha256', hawk_auth_key);
//passing the data to be hashed
const data = hmac.update(hawk_header);
//Creating the hmac in the required format
const gen_hmac = data.digest('base64');
console.log(gen_hmac)
//ETCKAQIzJsKGXJSaMzqpe00bsufrzB1g+8IS2Y9cPZM=
📄hawk-authentication.jsวิธีการคำนวณหาเลข mac และ มีข้อมูล payload โดยใช้ขั้นตอนดังนี้
const crypto = require('crypto')
const hawk_auth_id = 'dh37fgj492je';
const hawk_auth_key = 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn';
const method = 'GET';
const nonce = 'j4h3g2';
const timestamp = 1669306825;
//https://postman-echo.com/auth/hawk
const host = 'postman-echo.com';
const resource = '/auth/hawk';
const port = '443'; //example: 80,433
const ext = 'some-app-ext-data'
const hawk_payload =`hawk.1.payload
application/json
{prop:"Some Value"}`
console.log(hawk_payload)
const hmac_payload = crypto.createHmac('sha256', hawk_auth_key);
//passing the data to be hashed
const data_payload = hmac_payload.update(hawk_payload);
//Creating the hmac in the required format
const gen_hmac_playload = data_payload.digest('base64');
console.log(gen_hmac_playload)
//rnhCXzcyvQjtrkouE0e6NF12WhvI5xy0dOL9EKQJrZ0=
// request string (newline terminated values):
const hawk_header = `hawk.1.header\n${timestamp}\n${nonce}\n${method}\n${resource}\n${host}\n${port}\n${gen_hmac_playload}\n${ext}\n`
console.log(hawk_header)
const hmac = crypto.createHmac('sha256', hawk_auth_key);
//passing the data to be hashed
data = hmac.update(hawk_header);
//Creating the hmac in the required format
gen_hmac = data.digest('base64');
console.log(gen_hmac)
//TpYOFWAbltqCytxOxevx4pQuFgUo+Vy3G5mGwkDxfVY=
📄hawk-authentication-payload.jsAWS Signature
NTLM authentication
Akamai EdgeGrid
สำหรับ Authentication Type ต่างๆ ของ Postman ก็จะประมาณนี้ครับ ขั้นตอนหลายๆ อย่างอาจจะซับซ่อนไปนิดหน่อยเดี่ยวจะพยายามอธิบายให้ดีกว่านี้นะ