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

  1. Nama Aplikasi : Masukkan Nama Aplikasi misalnya CAVS

  2. Lewati Otorisasi : Jika ini dicentang, selama otentikasi tidak akan ada pesan konfirmasi. Lewati Otorisasi berarti klien dianggap sebagai klien tepercaya.

  3. Lingkup : Daftar lingkup yang ditampilkan kepada pengguna bersamaan dengan pesan konfirmasi. lingkup dipisahkan oleh spasi.

  4. Redirect URIs : Daftar Redirect URIs dipisahkan oleh spasi.

  5. Default Redirect URIs : Redirect URI Default dari daftar Redirect URIs

  6. Jenis Hibah: pilih Authorization Code atau Implicit.

  7. Jenis Respons: pilih Code jika jenis hibah adalah Authorization Code atau pilih Token.

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 s256 atau plain.

  • code_challenge (string)

    (OPSIONAL) Dapat berupa base64encode(sha256(random_string)) jika code_challenge_method=s256 atau random_string jika code_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')) =&gt; 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&amp;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-urlencoded

Catatan: Endpoint ini juga dapat digunakan untuk mendapatkan token akses yang diperbarui. Cukup kirim refresh_token di 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&amp;code=wa1YuQMff2ZXEAu2ZBHLpJRQXcGZdr
         &amp;redirect_uri=https%3A%2F%2Fapp.getpostman.com%2Foauth2%2Fcallback&amp;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&amp;code=A1KBRoYAN1uxrLAcdGLmvPKsRQLvzj&amp;client_id=511cb2ac2d&amp;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_string yang digunakan selama Authorization Request dengan code_challenge_method dan code_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&amp;code=wa1YuQMff2ZXEAu2ZBHLpJRQXcGZdr
         &amp;redirect_uri=https%3A%2F%2Fapp.getpostman.com%2Foauth2%2Fcallback&amp;client_id=af615c2d3a&amp;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&amp;code=A1KBRoYAN1uxrLAcdGLmvPKsRQLvzj&amp;client_id=511cb2ac2d&amp;redirect_uri=https%3A%2F%2Fapp.getpostman.com%2Foauth2%2Fcallback&amp;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.

  • aud memiliki client_id terdaftar.

  • iss memiliki URL Server.

  • sub memiliki userid Pengguna.

  • roles memiliki peran pengguna.

  • exp memiliki waktu kedaluwarsa.

  • iat memiliki 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_token atau refresh_token, default ke access_token jika tidak ada yang diberikan

  • token

    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": "..."
}


Discard
Save

On this page

Review Changes ← Back to Content
Message Status Space Raised By Last update on