OAuth 2
Bagaimana cara mengatur OAuth 2?
OAuth 2.0 penyedia berdasarkan oauthlib sudah terintegrasi dalam frappe. Aplikasi pihak ketiga sekarang dapat mengakses sumber daya pengguna berdasarkan sistem Role dan Izin Pengguna. Untuk mengatur aplikasi agar dapat mengakses
OAuth 2 mendefinisikan empat peran
pemilik sumber daya
Entitas yang dapat memberikan akses ke sumber daya yang dilindungi. Ketika pemilik sumber daya adalah seorang individu, disebut sebagai end-user.
server sumber daya
Server yang menyimpan sumber daya yang dilindungi, mampu menerima dan merespons permintaan sumber daya yang dilindungi menggunakan token akses.
klien
Aplikasi yang membuat permintaan sumber daya yang dilindungi atas nama pemilik sumber daya dan dengan izinnya. Istilah "klien" tidak menyiratkan karakteristik implementasi tertentu (misalnya, apakah aplikasi berjalan di server, desktop, atau perangkat lain).
server otorisasi
Server yang mengeluarkan token akses ke klien setelah berhasil mengautentikasi pemilik sumber daya dan memperoleh otorisasi.
Atur Penyedia OAuth 2
Manajer Sistem dapat mengatur perilaku pesan konfirmasi sebagai Force atau Auto di Pengaturan Penyedia OAuth. Jika Force dipilih, sistem akan selalu meminta konfirmasi pengguna. Jika Auto dipilih, sistem akan meminta konfirmasi hanya jika tidak ada token aktif untuk pengguna.
Buka Setup > Integrations > OAuth Provider Settings

Tambahkan Server Utama
Ini adalah server utama yang menampung semua pengguna. Misalnya https://frappe.io. Untuk mengatur ini sebagai server utama, buka Setup > Integrations > Social Login Key dan tambahkan Frappe Social Login Key baru. Masukkan https://frappe.io di bidang Base URL. URL ini akan diulang di semua server Frappe lainnya yang terhubung ke server ini untuk mengautentikasi. Secara efektif, ini adalah Penyedia Identitas Utama (IDP).
Di bawah server ini tambahkan sebanyak OAuth Client yang diperlukan.
Tambahkan Aplikasi Klien
Sebagai Manajer Sistem, buka Setup > Integrations > OAuth Client

Untuk menambahkan klien, isi detail berikut
Nama Aplikasi : Masukkan Nama Aplikasi misalnya CAVS
Lewati Otorisasi : Jika ini dicentang, selama otentikasi tidak akan ada pesan konfirmasi. Lewati Otorisasi berarti klien dianggap sebagai klien tepercaya.
Lingkup : Daftar lingkup yang ditampilkan kepada pengguna bersamaan dengan pesan konfirmasi. lingkup dipisahkan oleh spasi.
Redirect URIs : Daftar Redirect URIs dipisahkan oleh spasi.
Default Redirect URIs : Redirect URI Default dari daftar Redirect URIs
Jenis Hibah: pilih
Authorization CodeatauImplicit.Jenis Respons: pilih
Codejika jenis hibah adalahAuthorization Codeatau pilihToken.
Menggunakan OAuth
Gunakan header Authorization: Bearer <access_token> untuk melakukan permintaan otentikasi. Anda dapat menerima bearer token dengan menggabungkan dua permintaan berikut.
Berikut adalah pengenalan luar biasa tentang OAuth: OAuth 2.0 and OpenID Connect (in plain English)
GET /api/method/frappe.integrations.oauth2.authorize
Dapatkan kode otorisasi dari pengguna untuk mengakses ERPNext atas namanya.
Param (dalam query):
client_id (string)
ID dari aplikasi OAuth2 Anda
state (string)
Nilai sembarang yang digunakan oleh aplikasi klien Anda untuk menjaga status antara permintaan dan callback. Server otorisasi menyertakan nilai ini saat mengarahkan kembali user-agent ke klien. Parameter ini harus digunakan untuk mencegah cross-site request forgery.
response_type (string)
"code"
scope (string)
Lingkup akses yang harus diberikan ke aplikasi Anda.
redirect_uri (string)
Callback URI yang akan diarahkan pengguna setelah aplikasi diotorisasi. Kode otorisasi kemudian dapat diekstraksi dari param.
code_challenge_method (string)
(OPSIONAL) Dapat berupa
s256atauplain.code_challenge (string)
(OPSIONAL) Dapat berupa
base64encode(sha256(random_string))jikacode_challenge_method=s256ataurandom_stringjikacode_challenge_method=plain. Referensi: https://tools.ietf.org/html/rfc7636#appendix-A
Contoh:
curl -X POST https://{your frappe instance}/api/method/frappe.integrations.oauth2.authorize \
--data-urlencode 'client_id=511cb2ac2d' \
--data-urlencode 'state=444' \
# base64encode(sha256('420')) => 21XaP8MJjpxCMRxgEzBP82sZ73PRLqkyBUta1R309J0
# --data-urlencode 'code_verifier=21XaP8MJjpxCMRxgEzBP82sZ73PRLqkyBUta1R309J0' \
--data-urlencode 'response_type=code'
--data-urlencode 'scope=openid%20all' \
--data-urlencode 'redirect_uri=https://app.getpostman.com/oauth2/callback'
Mengembalikan:
Kode HTTP: 200
text/html
Ini akan membuka halaman otorisasi yang kemudian mengarahkan Anda ke
redirect_uri.
Jika pengguna mengklik 'Izinkan', redirect URI akan dipanggil dengan kode otorisasi di parameter query:
https://{redirect uri}?code=plkj2mqDLwaLJAgDBAkyR1W8Co08Ud&state=444
Jika pengguna mengklik 'Tolak' Anda akan menerima error:
https://{redirect uri}?error=access_denied
Pertukaran Token untuk Authorization Code Grant dengan ID Token
POST /api/method/frappe.integrations.oauth2.get_token
Header Content-Type: application/x-www-form-urlencodedCatatan: Endpoint ini juga dapat digunakan untuk mendapatkan token akses yang diperbarui. Cukup kirim
refresh_tokendi body permintaan.
Tukar kode otorisasi (diperoleh di atas) untuk token akses.
Param (dalam body):
grant_type (string)
"authorization_code"
code (string)
Kode otorisasi diterima di redirect URI.
client_id (string)
ID dari aplikasi OAuth2 Anda
redirect_uri (string)
Redirect URI terdaftar dari aplikasi klien
Contoh:
curl -X POST https://{your_instance}/api/method/frappe.integrations.oauth2.get_token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Accept: application/json' \
-d 'grant_type=authorization_code&code=wa1YuQMff2ZXEAu2ZBHLpJRQXcGZdr
&redirect_uri=https%3A%2F%2Fapp.getpostman.com%2Foauth2%2Fcallback&client_id=af615c2d3a'
Untuk tujuan pengujian Anda juga dapat mengirimkan parameter di URL seperti ini (dan buka di browser):
https://{your_instance}/api/method/frappe.integrations.oauth2.get_token?grant_type=authorization_code&code=A1KBRoYAN1uxrLAcdGLmvPKsRQLvzj&client_id=511cb2ac2d&redirect_uri=https%3A%2F%2Fapp.getpostman.com%2Foauth2%2Fcallback
Mengembalikan:
{
"access_token": "pNO2DpTMHTcFHYUXwzs74k6idQBmnI",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "cp74cxbbDgaxFuUZ8Usc7egYlhKbH1",
"scope": "openid all",
"id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o"
}
Pertukaran Token untuk Authorization Code Grant dengan ID Token (PKCE)
POST /api/method/frappe.integrations.oauth2.get_token
Header Content-Type: application/x-www-form-urlencoded
Tukar kode otorisasi (diperoleh di atas) untuk token akses.
Param (dalam body):
grant_type (string)
"authorization_code"
code (string)
Kode otorisasi diterima di redirect URI.
client_id (string)
ID dari aplikasi OAuth2 Anda
redirect_uri (string)
Redirect URI terdaftar dari aplikasi klien
code_verifier (string)
random_stringyang digunakan selamaAuthorization Requestdengancode_challenge_methoddancode_challenge.
Content-Type: application/x-www-form-urlencoded
Contoh:
curl -X POST https://{your_instance}/api/method/frappe.integrations.oauth2.get_token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Accept: application/json' \
-d 'grant_type=authorization_code&code=wa1YuQMff2ZXEAu2ZBHLpJRQXcGZdr
&redirect_uri=https%3A%2F%2Fapp.getpostman.com%2Foauth2%2Fcallback&client_id=af615c2d3a&code_verifier=420'
Untuk tujuan pengujian Anda juga dapat mengirimkan parameter di URL seperti ini (dan buka di browser):
https://{your_instance}/api/method/frappe.integrations.oauth2.get_token?grant_type=authorization_code&code=A1KBRoYAN1uxrLAcdGLmvPKsRQLvzj&client_id=511cb2ac2d&redirect_uri=https%3A%2F%2Fapp.getpostman.com%2Foauth2%2Fcallback&code_verifier=420
Mengembalikan:
{
"access_token": "pNO2DpTMHTcFHYUXwzs74k6idQBmnI",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "cp74cxbbDgaxFuUZ8Usc7egYlhKbH1",
"scope": "openid all",
"id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o"
}
Endpoint Revoke Token
POST /api/method/frappe.integrations.oauth2.revoke_token
Header: Content-Type: application/x-www-form-urlencoded
Endpoint untuk mencabut token.
Param:
token
Token akses yang akan dicabut.
Mengembalikan:
Selalu mengembalikan respons kosong dengan kode status HTTP 200.
{}Open ID Connect id_token
ID Token adalah JWT.
audmemilikiclient_idterdaftar.issmemiliki URL Server.submemiliki userid Pengguna.rolesmemiliki peran pengguna.expmemiliki waktu kedaluwarsa.iatmemiliki waktu penerbitan.
Contoh: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkouIERvZSIsImVtYWlsIjoiakBkb2UuY29tIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDIwMjIsImF1ZCI6ImNsaWVudF9pZCJ9.ZEdnrHjLbArahVTN19b4zoRFoBO5a2BakRkR82O1VU8
Verifikasi dan ekstraksi dengan PyJWT.
import jwt
id_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkouIERvZSIsImVtYWlsIjoiakBkb2UuY29tIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDIwMjIsImF1ZCI6ImNsaWVudF9pZCIsInJvbGVzIjpbIlN5c3RlbSBNYW5hZ2VyIiwiU2FsZXMgTWFuYWdlciJdLCJub25jZSI6Ijc4OTEyMyIsImlzcyI6Imh0dHBzOi8vZXJwLmV4YW1wbGUuY29tIn0.F8Wbh5dtD1loZPltJLj_sqF9DZNeBvEbo-ITtf3UPqk"
client_id = 'client_id'
client_secret = 'client_secret'
payload = jwt.decode(
id_token,
audience=client_id,
key=client_secret,
algorithm="HS256",
options={"verify_exp": False}, # Enabled by default to verify expiration time
)
print(payload)
# Output
{'sub': '1234567890', 'name': 'J. Doe', 'email': 'j@doe.com', 'iat': 1516239022, 'exp': 1516242022, 'aud': 'client_id', 'roles': ['System Manager', 'Sales Manager'], 'nonce': '789123', 'iss': 'https://erp.example.com'}
OpenID User Info Endpoint
Permintaan
GET /api/method/frappe.integrations.oauth2.openid_profile
Header: Authorization: Bearer valid_access_token
Respons
{
"sub": "1234567890",
"name": "J. Doe",
"given_name": "J",
"family_name": "Doe",
"iss": "https://erp.example.com",
"picture": "https://erp.example.com/files/jdoe.jpg",
"email": "j@doe.com",
"iat": 1516239022,
"exp": 1516242022,
"aud": "client_id",
"roles": ["System Manager", "Sales Manager"]
}
Introspect Token Endpoint
POST /api/method/frappe.integrations.oauth2.introspect_token
Header: Content-Type: application/x-www-form-urlencoded
Endpoint untuk introspeksi token.
Param:
tokentypehint
access_tokenataurefresh_token, default keaccess_tokenjika tidak ada yang diberikantoken
Token Akses atau Refresh Token yang akan diintrospeksi. Bergantung pada tokentypehint
Mengembalikan:
{
"client_id": "511cb2ac2d",
"trusted_client": 1,
"active": true,
"exp": 1619523326,
"scope": "openid all",
"sub": "1234567890",
"name": "J. Doe",
"given_name": "J",
"family_name": "Doe",
"iss": "https://erp.example.com",
"picture": "https://erp.example.com/files/jdoe.jpg",
"email": "j@doe.com",
"iat": 1516239022,
"exp": 1516242022,
"aud": "511cb2ac2d",
"roles": ["System Manager", "Sales Manager"]
}
ATAU
{
"active": false,
"_server_messages": "..."
}