Hướng dẫn php oidc - php oidc

Thư viện máy chủ OAuth2 cho PHP

Triển khai máy chủ OAuth 2.0 một cách sạch sẽ vào ứng dụng PHP của bạn. Tải về mã từ GitHub để bắt đầu.

Show

Nội dung chính

  • Thư viện máy chủ OAuth2 cho PHP
  • Cài đặt
  • Bắt đầu với thư viện này
  • Rất khuyến khích bạn kiểm tra thẻ Header: { "typ": "JWT", "alg": "RS256" } Payload: { "aud": "testclient", "jti": "a4c3d9a9d6ac5ff1b5", "iat": 1662814887, "nbf": 1662814887, "exp": 1662818487, "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6", "scopes": [ "blog_read", "profile", "email" ], "kid": "1", "custom": { "foo": "bar" } } Signature: [Binary signature]0 để đảm bảo ứng dụng của bạn không bị hỏng từ các vấn đề tương thích ngược. Tuy nhiên, nếu bạn muốn ở lại trên mép phát triển chảy máu, bạn có thể đặt điều này thành Header: { "typ": "JWT", "alg": "RS256" } Payload: { "aud": "testclient", "jti": "a4c3d9a9d6ac5ff1b5", "iat": 1662814887, "nbf": 1662814887, "exp": 1662818487, "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6", "scopes": [ "blog_read", "profile", "email" ], "kid": "1", "custom": { "foo": "bar" } } Signature: [Binary signature]1 thay thế.
  • Những gì chúng ta sẽ xây dựng
  • OAuth2 là gì?
  • Một chút thuật ngữ
  • Dòng OAuth2
  • Thông tin khách hàng cấp
  • Tài nguyên chủ sở hữu thông tin xác thực
  • Tài trợ ngầm
  • Làm mới mã thông báo cấp
  • Luồng cấp mã ủy quyền
  • OAuth2 vs OpenID Connect
  • Ủy quyền so với xác thực
  • Xác thực với OIDC
  • Mã thông báo web JSON (JWT) là gì?
  • Điều kiện tiên quyết
  • Thiết lập ứng dụng máy chủ
  • Tạo các phím.
  • Định cấu hình gói máy chủ OAuth2
  • Tạo ra các thực thể của chúng tôi
  • openssl genrsa -out var/keys/private.key openssl rsa -in var/keys/private.key -pubout -out var/keys/public.key4-Mối quan hệ nhiều người với thực thể openssl genrsa -out var/keys/private.key openssl rsa -in var/keys/private.key -pubout -out var/keys/public.key5
  • Để làm điều này, chúng ta cần ghi đè thực thể truy cập được cung cấp bởi gói.
  • Trường "Tùy chỉnh" chỉ là một ví dụ về cách chúng ta có thể thêm dữ liệu tùy ý vào JWT. Trường "Kid" quan trọng hơn một chút - chúng tôi sẽ sử dụng điều này sau để xác định khóa được sử dụng để ký JWT khi chúng tôi xác minh nó. Nhưng đối với hướng dẫn, chúng tôi sẽ mã hóa nó là "1".
  • Gói xác định một số sự kiện nhất định mà chúng ta có thể sử dụng để nối vào xử lý yêu cầu của máy chủ OAuth2.
  • Tạo API mẫu và điểm cuối của JWKS
  • Tạo bộ điều khiển trang đồng ý
  • Cấu hình tường lửa
  • Ứng dụng khách hàng của chúng tôi
  • $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password)); $server = new OAuth2\Server($storage); $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like! $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();04 - Bí mật của khách hàng
  • Thử nó ra
  • Bình luận
  • OAuth2 được sử dụng để làm gì?
  • OAuth 2.0 trong API Web là gì?
  • Làm thế nào sử dụng OAuth 2.0 cho các cuộc gọi API REST trong PHP?
  • OAuth có nghĩa là gì?

Yêu cầu

Php 5.3.9+ là cần thiết cho thư viện này. Tuy nhiên, có một nhánh phát hành và phát triển ổn định cho PHP 5.2.x-5.3.8. is required for this library. However, there is a stable release and development branch for PHP 5.2.x-5.3.8 as well. is required for this library. However, there is a stable release and development branch for PHP 5.2.x-5.3.8 as well.

Cài đặt

Thư viện này tuân theo các tiêu chuẩn Zend PSR-0. Một số trình tải tự động tồn tại có thể tự động tải thư viện này vì lý do đó, nhưng nếu bạn không sử dụng một bộ phận, bạn có thể đăng ký

header.payload.signature
8:

PHP

require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();

Sử dụng nhà soạn nhạc? Thực hiện lệnh sau:

header.payload.signature
9

Điều này sẽ thêm yêu cầu cho Composer.json và cài đặt thư viện.

Rất khuyến khích bạn kiểm tra thẻ

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
0 để đảm bảo ứng dụng của bạn không bị hỏng từ các vấn đề tương thích ngược. Tuy nhiên, nếu bạn muốn ở lại trên mép phát triển chảy máu, bạn có thể đặt điều này thành
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
1 thay thế.

Bắt đầu với thư viện này

Rất khuyến khích bạn kiểm tra thẻ Header: { "typ": "JWT", "alg": "RS256" } Payload: { "aud": "testclient", "jti": "a4c3d9a9d6ac5ff1b5", "iat": 1662814887, "nbf": 1662814887, "exp": 1662818487, "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6", "scopes": [ "blog_read", "profile", "email" ], "kid": "1", "custom": { "foo": "bar" } } Signature: [Binary signature]0 để đảm bảo ứng dụng của bạn không bị hỏng từ các vấn đề tương thích ngược. Tuy nhiên, nếu bạn muốn ở lại trên mép phát triển chảy máu, bạn có thể đặt điều này thành Header: { "typ": "JWT", "alg": "RS256" } Payload: { "aud": "testclient", "jti": "a4c3d9a9d6ac5ff1b5", "iat": 1662814887, "nbf": 1662814887, "exp": 1662818487, "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6", "scopes": [ "blog_read", "profile", "email" ], "kid": "1", "custom": { "foo": "bar" } } Signature: [Binary signature]1 thay thế.

PHP

Sử dụng nhà soạn nhạc? Thực hiện lệnh sau:

Điều này sẽ thêm yêu cầu cho Composer.json và cài đặt thư viện.

Rất khuyến khích bạn kiểm tra thẻ

  1. Bắt đầu với thư viện nàyOAuth in 8 Steps screencast from Knp University: OAuth in 8 Steps screencast from Knp University:

    Hướng dẫn php oidc - php oidc

  2. Nhìn qua các ví dụ sách nấu ăn là cách tốt nhất để bắt đầu. Đối với những người chỉ đọc lướt các tài liệu cho các mẫu mã, đây là một ví dụ về việc triển khai máy chủ OAuth2 trần:OAuth2 Demo Application and view the source code for examples using a variety of grant types. OAuth2 Demo Application and view the source code for examples using a variety of grant types.

  3. $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
  4. Xem các khái niệm chính để biết thêm thông tin về cách thư viện này hoạt động.

Học tiêu chuẩn OAuth2.0

Nếu bạn chưa quen với OAuth2, tôi đánh giá cao OAuth trong 8 bước screencast từ Đại học KNP:

  1. Nhà
  2. PHP
  3. Xây dựng máy chủ OAuth2 của riêng bạn với PHP và Symfony

Trong hướng dẫn này, tôi sẽ hướng dẫn bạn thông qua mã để xây dựng máy chủ OAuth2 của riêng bạn bằng thư viện máy chủ OAuth2 của Php League và gói Symfony tương ứng của họ.

Gói không quá tốt tài liệu kể từ thời điểm viết, vì vậy tôi nghĩ rằng điều này sẽ hữu ích không chỉ như một hướng dẫn trong việc tạo một ứng dụng máy chủ đầy đủ và trình diễn máy khách đơn giản mà còn là một tài liệu tham khảo dễ hiểu (hy vọng) để hiểu Tất cả các khái niệm liên quan.

Những gì chúng ta sẽ xây dựng

Chúng tôi sẽ xây dựng một máy chủ OAuth2 đơn giản cho phép người dùng đăng nhập và ủy quyền cho ứng dụng riêng (nghĩa là bên thứ ba, máy khách) để truy cập dữ liệu của họ.

Trong ứng dụng Symfony hoạt động như máy chủ, điều này sẽ có dạng mã thông báo truy cập được cấp cho ứng dụng máy khách có thể được sử dụng như một phần của yêu cầu API để xác thực với tư cách là người dùng trên máy chủ, sẽ có vai trò bổ sung được cấp Bên trong mã thông báo bảo mật của họ tương ứng với các quyền cụ thể mà họ đã cho phép khách hàng truy cập.

Điều này có nghĩa là bên trong ứng dụng máy chủ của chúng tôi, chúng tôi có thể xây dựng các điểm cuối API được giới hạn trong các yêu cầu có mã thông báo truy cập để cấp các quyền cụ thể.

Ứng dụng máy khách sẽ là tập lệnh PHP đơn giản cho phép người dùng đăng nhập và sau đó thực hiện yêu cầu API vào ứng dụng máy chủ, sẽ trả về một số dữ liệu về người dùng.

Mã mẫu hoàn chỉnh cho hướng dẫn này có sẵn trên GitHub của tôi và được ghi chép thuận tiện để bạn có thể chạy nó cục bộ mà không phải cài đặt bất kỳ phụ thuộc nào.

Ngoài ra còn có một bản demo trực tiếp có sẵn tại https://davegebler.com/oauth2client Chỉ cần đăng nhập bằng tên người dùng

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
2 và mật khẩu
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
3 và bạn sẽ có thể gọi API trên https://auth.davegebler.com/api /Kiểm tra với mã thông báo truy cập của bạn như một mã thông báo mang trong tiêu đề ủy quyền.

Trước khi chúng ta vào mã, chúng ta hãy xem xét kỹ hơn OAuth2 và dòng chảy chúng ta sẽ sử dụng.

OAuth2 là gì?

OAuth2 là một giao thức được tiêu chuẩn hóa để ủy quyền quyền truy cập vào tài nguyên trên máy chủ thay mặt cho chủ sở hữu.

Hãy tưởng tượng bạn là người dùng ứng dụng A. Ứng dụng A giữ một số dữ liệu về bạn. Có thể đó là tên của bạn, địa chỉ email, ảnh hoặc có thể đó là dữ liệu nhạy cảm hơn như chi tiết tài khoản ngân hàng hoặc hồ sơ y tế của bạn.

Ứng dụng B là một ứng dụng riêng mà bạn cũng sử dụng. Ứng dụng B muốn truy cập một số dữ liệu ứng dụng A nắm giữ bạn, thường là để lưu bạn cần nhập lại thông tin đó ở hai nơi khác nhau, để cung cấp cho bạn sự thuận tiện và trải nghiệm tốt hơn.

Để làm điều này, ứng dụng B cần hai điều; Sự đồng ý của bạn về chính xác những gì nó có thể nhận được và một cách an toàn để truy cập dữ liệu một khi bạn đã cung cấp nó.

Đây là nơi OAuth 2 xuất hiện. Nó thay thế đặc tả OAuth ban đầu và hiện là giao thức được sử dụng rộng rãi nhất để ủy quyền truy cập vào tài nguyên trên máy chủ.

Một chút thuật ngữ

OAuth2 là một giao thức, có nghĩa là đó là một bộ quy tắc xác định cách hai hoặc nhiều bên có thể tương tác với nhau.

OAuth2 sử dụng một số thuật ngữ cụ thể để mô tả các phần khác nhau liên quan đến việc chia sẻ dữ liệu này.

Chủ sở hữu tài nguyên là bạn, người dùng. Bạn là người sở hữu một số dữ liệu mà bạn muốn chia sẻ với một ứng dụng khác. Dữ liệu bạn sở hữu được gọi là tài nguyên.

Ứng dụng mà bạn muốn chia sẻ dữ liệu của mình được gọi là máy khách. Đây là ứng dụng bạn sẽ ủy quyền truy cập dữ liệu của bạn. Đây cũng là ứng dụng sẽ yêu cầu sự đồng ý của bạn truy cập dữ liệu của bạn.

Máy chủ ủy quyền là ứng dụng có thể cấp quyền truy cập vào dữ liệu của bạn và khách hàng nào sẽ gửi cho bạn để có được sự đồng ý của bạn.

Điều này có thể hoặc không phải là máy chủ giống như máy chủ tài nguyên, đây là ứng dụng thực sự giữ dữ liệu của bạn.

Sự đồng ý của bạn sẽ được trao cho máy chủ ủy quyền, sau đó sẽ phát hành mã thông báo truy cập cho máy khách.

Sau đó, khách hàng sẽ sử dụng mã thông báo truy cập này để truy cập dữ liệu của bạn trên máy chủ tài nguyên.

Sự đồng ý của bạn sẽ được giới hạn trong phạm vi của mã thông báo truy cập, đây là tập hợp các quyền mà khách hàng đã được bạn cấp. Đây là những loại dữ liệu cụ thể mà bạn đồng ý rằng khách hàng có thể truy cập - ví dụ: có thể máy chủ tài nguyên là ngân hàng của bạn và bạn rất vui khi cho phép khách hàng truy cập tên, địa chỉ email và danh sách các giao dịch ghi nợ gần đây của bạn , nhưng không phải là chi tiết tài khoản ngân hàng khác của bạn.

Cuối cùng, sự đồng ý của bạn sẽ bị hủy bỏ bởi máy chủ ủy quyền nếu bạn quyết định rút nó.

Dòng OAuth2

OAuth2 xác định một luồng cụ thể để ủy quyền truy cập vào tài nguyên trên máy chủ. Lưu lượng này được gọi là tài trợ mã ủy quyền.

Có những dòng chảy khác được xác định trong đặc tả OAuth2, nhưng đây là phổ biến nhất và chúng tôi sẽ sử dụng trong hướng dẫn này.

Đây cũng là dòng chảy duy nhất tôi thực sự phải làm việc trong thế giới thực với tư cách là một nhà phát triển web, vì vậy tôi sẽ không đến với những người khác quá chi tiết ở đây, nhưng là một cái nhìn tổng quan nhanh chóng:

Thông tin khách hàng cấp

Đây là dòng chảy đơn giản nhất. Nó được sử dụng khi khách hàng hành động thay mặt mình, thay vì thay mặt cho người dùng, tức là khi chính khách hàng là chủ sở hữu tài nguyên. Điều này được sử dụng chủ yếu trong giao tiếp máy chủ đến máy chủ.

Tài nguyên chủ sở hữu thông tin xác thực

Điều này được sử dụng khi máy khách đang hành động thay mặt cho người dùng, nhưng người dùng đã cung cấp thông tin đầy đủ cho khách hàng để sử dụng trong tương lai. Điều này được sử dụng chủ yếu trong các ứng dụng di động và chỉ nên được sử dụng khi người dùng có mức độ tin cậy cao vào ứng dụng máy khách.

Tài trợ ngầm

Đây là phiên bản đơn giản hóa của cấp mã ủy quyền, được sử dụng khi máy khách là ứng dụng web không thể giữ được mã thông báo bí mật mà không đưa nó ra thế giới rộng hơn, chẳng hạn như ứng dụng JavaScript một trang không có phía máy chủ thành phần. Nó không được khuyến nghị sử dụng trong hầu hết các trường hợp và nên tránh nếu có thể.

Đây là phiên bản của Trợ cấp Mã ủy quyền hiện là giải pháp thay thế được ưu tiên cho khoản tài trợ ngầm. Sự khác biệt là ứng dụng máy khách về cơ bản tạo ra một bí mật tạm thời dưới dạng trình xác minh mã, sau đó nó băm để tạo ra một thách thức mã. Thử thách mã này được gửi đến máy chủ ủy quyền, sau đó gửi lại cho ứng dụng máy khách cùng với mã ủy quyền. Sau đó, ứng dụng máy khách gửi mã ủy quyền và bộ xác minh mã đến máy chủ ủy quyền. Sau đó, máy chủ ủy quyền đã băm bộ xác minh mã và so sánh nó với thách thức mã mà nó nhận được trước đó. Nếu chúng khớp, mã thông báo truy cập có thể được ban hành.

Làm mới mã thông báo cấp

Điều này được sử dụng khi khách hàng đã được cấp mã thông báo truy cập với thời gian tồn tại hạn chế và cần có khả năng gia hạn mà không phải thông qua luồng cấp ủy quyền đầy đủ.

Luồng cấp mã ủy quyền

Luồng cấp ủy quyền hoạt động như thế này:

  1. Máy khách gửi người dùng trực tiếp đến máy chủ ủy quyền, trong trình duyệt của họ, cùng với một số thông tin về chính nó và các quyền mà họ muốn yêu cầu.
  2. Người dùng được trình bày với màn hình đăng nhập và được yêu cầu đăng nhập.
  3. Người dùng được trình bày với màn hình đồng ý và được yêu cầu cấp cho khách hàng các quyền mà họ đã yêu cầu.
  4. Người dùng có thể cho phép hoặc từ chối yêu cầu này.
    1. Nếu người dùng từ chối yêu cầu, máy chủ ủy quyền sẽ chuyển hướng người dùng trở lại máy khách bằng thông báo lỗi.
  5. Nếu người dùng cho phép yêu cầu, máy chủ ủy quyền sẽ chuyển hướng người dùng trở lại máy khách bằng mã ủy quyền.
  6. Sau đó, khách hàng sẽ gửi mã ủy quyền này đến máy chủ ủy quyền, cùng với mã thông báo bí mật của riêng mình, để có được mã thông báo truy cập.
  7. Sau đó, khách hàng sẽ sử dụng mã thông báo truy cập này để truy cập máy chủ tài nguyên thay mặt cho người dùng.

OAuth2 vs OpenID Connect

OAuth2 là một giao thức để ủy quyền quyền truy cập vào tài nguyên trên máy chủ. OpenID Connect là một giao thức cho người dùng xác thực.

OpenID Connect (thường được viết tắt thành OIDC) được xây dựng trên đỉnh OAuth2. Bạn có thể nghĩ về nó như là một việc sử dụng và mở rộng theo quan điểm của giao thức OAuth2, để cho phép xác thực và quản lý người dùng.

Ủy quyền so với xác thực

Bạn sẽ thấy hai thuật ngữ này đã tăng lên rất nhiều trong thế giới điện toán.

Xác thực là về việc thiết lập bản sắc. Đó là về việc chứng minh bạn là ai. Điều này không nhất thiết có nghĩa là bản sắc trong thế giới thực của bạn; Danh tính của bạn trong bối cảnh này có thể đơn giản như bạn là người có quyền truy cập vào một địa chỉ email cụ thể.

Ủy quyền là về những gì bạn được phép làm. Trong hầu hết các hệ thống, bạn sẽ cần phải được xác thực trước khi bạn có thể được ủy quyền để làm bất cứ điều gì.

Hãy tưởng tượng tôi xuất hiện ở số 10 Downing Street và tôi cho người xem cảnh sát tại cổng hộ chiếu của tôi. Cảnh sát có thể kiểm tra hộ chiếu của tôi, nhìn tôi, hài lòng rằng hộ chiếu của tôi là chính hãng và tôi là người trong hình trên hộ chiếu. Bây giờ tôi đã được xác thực; Tôi đã chứng minh một cách hợp lý rằng tôi là Dave Gebler.

Nhưng có phải là Dave Gebler có nghĩa là tôi được phép vào số 10? Không, vì tôi không được phép làm như vậy.

Đó là xác thực so với ủy quyền.

Xác thực với OIDC

Vì vậy, những gì OIDC làm như một lớp trên đầu OAuth2 được cung cấp một bộ quy tắc tiêu chuẩn mà ứng dụng khách có thể sử dụng một ứng dụng khác mà nó tin tưởng để xác thực người dùng, để cung cấp dữ liệu về danh tính của người dùng đó.

OIDC thực hiện điều này bằng cách cung cấp một bộ khiếu nại tiêu chuẩn mà máy chủ xác thực có thể cung cấp cho ứng dụng máy khách.

Khiếu nại chỉ đơn giản là những thông tin về người dùng. Một số khiếu nại OIDC tiêu chuẩn là:

  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    4 - Mã định danh duy nhất của người dùng do tổ chức phát hành giữ
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    5 - Tên đầy đủ của người dùng
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    6 - Tên được cung cấp của người dùng
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    7 - Tên gia đình của người dùng
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    8 - URL hồ sơ của người dùng
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    9 - URL ảnh hồ sơ của người dùng
  • require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
    OAuth2\Autoloader::register();
    40 - Địa chỉ email của người dùng
  • require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
    OAuth2\Autoloader::register();
    41 - liệu địa chỉ email của người dùng có được xác minh thành công
  • require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
    OAuth2\Autoloader::register();
    42 - Số điện thoại của người dùng
  • require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
    OAuth2\Autoloader::register();
    43 - số điện thoại của người dùng đã được xác minh thành công

Có những người khác, nhưng như chúng ta có thể thấy - mỗi tuyên bố là một phần thông tin về người dùng là ai.

Sau đó, trường hợp sử dụng phổ biến nhất của OIDC là cho phép người dùng sử dụng dữ liệu được giữ về họ bằng một ứng dụng để tạo tài khoản và đăng nhập vào ứng dụng khác.

Nói cách khác, đăng nhập xã hội của bạn - các nút "Đăng nhập với Google / Facebook / Twitter" mà bạn thấy trên rất nhiều trang web - tất cả đều được xây dựng trên đỉnh OIDC.

Mã thông báo web JSON (JWT) là gì?

Trong khi OAuth2 trả về mã thông báo truy cập cho máy khách, thì thường được sử dụng để truy cập API trên máy chủ tài nguyên, OIDC trả về mã thông báo ID chứa thông tin nhận dạng trực tiếp về người dùng.

Do đó, sự khác biệt là một máy khách được dự định phân tích và đọc mã thông báo ID trực tiếp.

OIDC sử dụng một định dạng cụ thể được gọi là mã thông báo web JSON (JWTS) để mã hóa thông tin này.

JWT là một chuỗi văn bản được tạo thành từ ba phần, cách nhau bởi các dấu chấm:

header.payload.signature

Mỗi phần trong ba phần này là một đối tượng JSON tiêu chuẩn.

Tiêu đề chứa thông tin về chính mã thông báo, đặc biệt là thuật toán được sử dụng để ký vào nó.

Tải trọng chứa dữ liệu thực tế, như một tập hợp các khiếu nại.

Chữ ký là chữ ký mật mã của tiêu đề và tải trọng, được sử dụng để xác minh rằng mã thông báo là cả xác thực và chưa được thay đổi.

Mỗi mảnh này sau đó được mã hóa base64.

Mặc dù OIDC đặc biệt bắt buộc việc sử dụng JWTS, OAuth2 không - mã thông báo truy cập có thể là bất kỳ chuỗi văn bản nào, miễn là nó xác định duy nhất người dùng và máy khách. Các ứng dụng máy khách OAuth2 không nên dựa vào mã thông báo truy cập được mã hóa ở bất kỳ định dạng cụ thể nào và họ không nên cố gắng giải mã hoặc đọc nó cho bất kỳ thông tin nào.

Điều đó nói rằng, hoàn toàn không có gì sai khi cung cấp mã thông báo truy cập OAuth2 ở định dạng JWT; Một lý do bạn có thể muốn làm điều này là để lưu trữ tất cả các thông tin cần thiết về người dùng và phạm vi bên trong mã thông báo truy cập, thay vì phải lưu trữ nó trong cơ sở dữ liệu. JWT sẽ được ký hợp đồng với khóa riêng của máy chủ ủy quyền và có thể được xác minh bởi máy chủ tài nguyên bằng khóa công khai.

Chúng tôi không xây dựng một máy chủ OIDC đầy đủ trong hướng dẫn này, nhưng máy chủ OAuth2 mà chúng tôi đang xây dựng sẽ cung cấp các mã thông báo truy cập ở định dạng JWT và chúng tôi sẽ sử dụng chữ ký của các mã thông báo này để xác minh rằng chúng xác thực trong ứng dụng máy khách mẫu của chúng tôi. Hầu hết các ứng dụng khách sẽ không cần phải làm điều này và sẽ coi mã thông báo truy cập là một chuỗi mờ, nhưng đó là một bài tập hữu ích để hiểu cách thức hoạt động của nó.

Do đó, bạn có thể sử dụng những gì bạn học ở đây để đi xa hơn với việc triển khai và phát hành mã thông báo ID hoặc xây dựng một máy chủ OIDC đầy đủ trên đầu nếu bạn muốn.

JWT được giải mã mà máy chủ của chúng tôi sẽ cung cấp sẽ trông như thế này:

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]

Điều kiện tiên quyết

Để làm theo với hướng dẫn này, tôi sẽ cho rằng bạn đã quen thuộc một cách hợp lý với Symfony.

Mã mẫu mà tôi đã cung cấp được xây dựng trên Symfony 6.1 và Php 8.1, mặc dù tôi cung cấp một tệp Docker Compose để giúp bạn dễ dàng đứng dậy và chạy.

Nếu bạn không sử dụng Docker, bạn sẽ cần cài đặt Php 8.1, cùng với các công cụ

require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
44 và
require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
45 CLI. Vui lòng đảm bảo bạn đã cài đặt OpenSSL trên hệ thống của mình; Chúng tôi sẽ cần điều này để tạo bàn phím riêng và công khai được sử dụng để ký hợp đồng với JWT của chúng tôi.
  • Nhận Symfony CLI
  • Nhận nhà soạn nhạc

Thiết lập ứng dụng máy chủ

Chúng tôi sẽ bắt đầu bằng cách tạo một ứng dụng Symfony mới để hoạt động như máy chủ OAuth2 của chúng tôi.

require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
4

Điều này sẽ tạo ra một ứng dụng Symfony mới trong thư mục

require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
46.

Chúng tôi cũng cần cài đặt gói máy chủ OAuth2 của Php League, nơi cung cấp tích hợp Symfony cho Thư viện Máy chủ OAuth2 của Php League.

header.payload.signature
4

Khi ứng dụng của bạn được tạo, hãy xem cấu hình mặc định. Trong dự án mẫu của mình, tôi đã sử dụng SQLite làm phụ trợ cơ sở dữ liệu để đơn giản, nhưng nếu bạn thích sử dụng mysql / postgres / bất cứ điều gì, hãy thoải mái.

Tạo các phím.

Trong thư mục

require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
47 của dự án Symfony của bạn, hãy tạo một thư mục con mới gọi là
require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
48 và chạy các lệnh OpenSSL sau:
header.payload.signature
7

Định cấu hình gói máy chủ OAuth2

Sau khi cài đặt, bạn sẽ cần tạo một tệp cấu hình mới trong dự án của mình, theo

require_once('/path/to/oauth2-server-php/src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
49
header.payload.signature
9

Và nhập các tuyến đường của bó bên trong

header.payload.signature
40
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
1

Tạo ra các thực thể của chúng tôi

Chúng tôi sẽ cần tạo một thực thể người dùng để đại diện cho người dùng ứng dụng của chúng tôi.

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
2

Tạo một thực thể người dùng bằng email là tên người dùng và bao gồm cả thuộc tính

header.payload.signature
41 thuộc loại UUID.

Sau đó, chúng tôi sẽ thực hiện một vài thay đổi nhỏ để chúng tôi có thể đăng nhập bằng địa chỉ email, nhưng cũng phát hành các mã thông báo truy cập trong đó ID của người dùng là UUID.

Trong

header.payload.signature
42 của bạn, đảm bảo nó thực hiện
header.payload.signature
43:
$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
0

Và thêm phương thức sau:

$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
1

Cuối cùng, trong thực thể

header.payload.signature
44, thêm phương thức sau:
$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
2

Gói sẽ bao gồm các thực thể chúng ta cần để đại diện cho các ứng dụng khách hàng, mã thông báo và mã ủy quyền, nhưng vẫn còn một vài thực thể mà chúng ta muốn tạo để lưu các sự đồng ý mà người dùng cấp cho các ứng dụng khách hàng và để mô tả các ứng dụng theo cách nào đó (Chúng tôi sẽ gắn bó với một cái tên đơn giản ngay bây giờ).

Tạo thêm hai thực thể:

$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
3

Tạo một thực thể

header.payload.signature
45 với các thuộc tính sau:
  • header.payload.signature
    46 - phím chính, số nguyên, tăng tự động
  • header.payload.signature
    47-Mối quan hệ một-một với thực thể
    header.payload.signature
    48
    • Tên cột được tham chiếu cho mối quan hệ này là
      header.payload.signature
      49.
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    5 - một chuỗi
  • header.payload.signature
    71 - một chuỗi hoặc văn bản

Bây giờ tạo một thực thể

header.payload.signature
72 với các thuộc tính sau:
  • header.payload.signature
    46 - phím chính, số nguyên, tăng tự động
  • header.payload.signature
    47-Mối quan hệ một-một với thực thể
    header.payload.signature
    48
  • Tên cột được tham chiếu cho mối quan hệ này là
    header.payload.signature
    49.
    • Tên cột được tham chiếu cho mối quan hệ này là
      header.payload.signature
      49.
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    5 - một chuỗi
  • header.payload.signature
    71 - một chuỗi hoặc văn bản
  • Bây giờ tạo một thực thể

header.payload.signature72 với các thuộc tính sau:

Bây giờ tạo một thực thể
header.payload.signature
72 với các thuộc tính sau:

openssl genrsa -out var/keys/private.key openssl rsa -in var/keys/private.key -pubout -out var/keys/public.key4-Mối quan hệ nhiều người với thực thể openssl genrsa -out var/keys/private.key openssl rsa -in var/keys/private.key -pubout -out var/keys/public.key5

header.payload.signature
47-Mối quan hệ nhiều người với thực thể
header.payload.signature
48
header.payload.signature
79 - DateTime
header.payload.signature
90 - một DateTime
$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
4
header.payload.signature
91 - một mảng đơn giản

header.payload.signature
94
$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
5

Ghi đè thực thể AccessToken gói

Đối với hướng dẫn này, chúng tôi sẽ bao gồm một số trường tùy chỉnh trong các JWTs mã thông báo truy cập của chúng tôi.

Để làm điều này, chúng ta cần ghi đè thực thể truy cập được cung cấp bởi gói.

Tạo một thực thể mới được gọi là

$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
6

header.payload.signature92 trong thư mục header.payload.signature93 với triển khai sau:

Những gì chúng tôi đã thêm ở đây qua triển khai mặc định là các trường "Kid" và "Tùy chỉnh".

Trường "Tùy chỉnh" chỉ là một ví dụ về cách chúng ta có thể thêm dữ liệu tùy ý vào JWT. Trường "Kid" quan trọng hơn một chút - chúng tôi sẽ sử dụng điều này sau để xác định khóa được sử dụng để ký JWT khi chúng tôi xác minh nó. Nhưng đối với hướng dẫn, chúng tôi sẽ mã hóa nó là "1".

Tiếp theo, chúng tôi sẽ tạo một kho lưu trữ tùy chỉnh để sử dụng thực thể này, kết thúc kho lưu trữ gói:

$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
7

Định cấu hình gói để sử dụng thực thể truy cập tùy chỉnh của chúng tôi

Bây giờ chúng tôi cần nói với ứng dụng của chúng tôi để sử dụng thực thể truy cập tùy chỉnh của chúng tôi.

Mở tệp

header.payload.signature95 và thêm cấu hình sau dưới khóa header.payload.signature96:

Chúng tôi sẽ sử dụng sự kiện

header.payload.signature
97 để giải quyết yêu cầu mã ủy quyền.
$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
8

Tạo một lớp mới được gọi là

header.payload.signature
98 trong thư mục
header.payload.signature
99 với triển khai sau:
$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
9

Bây giờ, bất cứ khi nào chúng tôi nhận được một yêu cầu mã AUTH, chúng tôi sẽ kiểm tra xem người dùng có đăng nhập không. Nếu có, chúng tôi sẽ kiểm tra xem họ có đồng ý cho khách hàng và phạm vi được yêu cầu không. Nếu họ có, chúng tôi sẽ giải quyết yêu cầu với giá trị đồng ý. Nếu họ không có, chúng tôi sẽ chuyển hướng họ đến trang đồng ý.

header.payload.signature
0

Chúng tôi sẽ thêm một điểm cuối khác bên trong bộ điều khiển này để xử lý biểu mẫu đồng ý một chút sau.

Cách bạn tạo kiểu cho mẫu đăng nhập của bạn là tùy thuộc vào bạn; Xem ứng dụng mẫu của tôi để biết một ví dụ. Đừng quên thêm mã thông báo CSRF vào biểu mẫu của bạn!

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
12

Tạo API mẫu và điểm cuối của JWKS

Bước tiếp theo là tạo và điều khiển chỉ mục.

Bộ điều khiển chỉ mục chỉ là một nơi thuận tiện, chúng tôi sẽ dán trang chủ đã đăng nhập, điểm cuối API mẫu sẽ được giới hạn cho người dùng có phạm vi OAuth2 nhất định và điểm cuối API khác sẽ có sẵn công khai. Cái cuối cùng này sẽ hiển thị một thứ gọi là bộ khóa JSON (JWKS) mà chúng ta sẽ sử dụng để xác minh JWTS chúng ta lấy lại từ máy chủ OAuth2.

Đây không phải là thứ chúng ta cần làm nghiêm ngặt cho mục đích OAuth2, nhưng nó cho thấy cách chúng ta có thể sử dụng hệ thống này để phát hành mã thông báo ID hoặc mã thông báo khác có chứa thông tin mà chúng ta muốn khách hàng có thể đọc và xác minh.

header.payload.signature
1

Sau đó thêm phần sau vào tệp

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
13:
header.payload.signature
2

Đây là điểm cuối chúng tôi sẽ gọi từ ứng dụng khách hàng của chúng tôi với mã thông báo truy cập của chúng tôi.

Tiếp theo, thêm một điểm cuối khác để đọc khóa công khai của máy chủ của chúng tôi và mã hóa thông tin về nó thành phản hồi JSON để tạo JWKS.

header.payload.signature
3

Tạo bộ điều khiển trang đồng ý

Bây giờ chúng ta cần tạo một điểm cuối của bộ điều khiển để xử lý trang đồng ý.

Đối với các mục đích của hướng dẫn, chúng tôi sẽ gắn bó tất cả logic của chúng tôi cho điều này bên trong một điểm cuối mới trong

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
14 hiện có (vì trang đồng ý là một phần của luồng ủy quyền).

Có một chút công bằng mà chúng tôi muốn xử lý ở đây:

  • Nhận client_id từ truy vấn yêu cầu và kiểm tra nó hợp lệ
  • Tìm khách hàng trong cơ sở dữ liệu
  • Tìm cấu hình máy khách tương ứng trong cơ sở dữ liệu, vì vậy chúng tôi có thể hiển thị tên ứng dụng / mô tả / bất cứ điều gì
  • Nhận phạm vi từ truy vấn yêu cầu và kiểm tra chúng là phạm vi hợp lệ cho máy khách
  • Kiểm tra xem người dùng đã chấp thuận cho máy khách và phạm vi này
  • Nếu họ có, chuyển hướng chúng trở lại máy chủ OAuth2 với giá trị đồng ý
  • Nếu họ không có, hãy hiển thị trang đồng ý
    • Nếu người dùng đã đồng ý với một số nhưng không phải tất cả các phạm vi được yêu cầu, hãy hiển thị trang đồng ý với phạm vi đồng ý được liệt kê
  • Nếu người dùng gửi trang đồng ý, hãy lưu sự đồng ý của họ và chuyển chúng trở lại máy chủ OAuth2 với giá trị đồng ý

Trong thế giới thực, chúng tôi sẽ đưa ra điều này đối với một số dịch vụ nhỏ hơn và nhằm mục đích giữ cho bộ điều khiển của chúng tôi mỏng nhất có thể.

Nhưng đối với hướng dẫn của chúng tôi, trong tệp

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
10 của bạn, hãy thêm chức năng sau cho tuyến
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
16:
header.payload.signature
4

Và tạo mẫu

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
17 bên trong thư mục
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
18. Mẫu phải chứa một biểu mẫu để gửi giá trị
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
19 và hiển thị bất kỳ sự đồng ý hiện có cũng như danh sách các sự đồng ý được yêu cầu.

Một ví dụ đầy đủ có thể được tìm thấy trong ứng dụng mẫu trên github của tôi.

Cấu hình tường lửa

Chúng tôi chỉ cần thực hiện một vài điều chỉnh cho tệp

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
20 của chúng tôi để đảm bảo các điểm cuối chúng tôi đã tạo được phơi bày hoặc bảo vệ khi thích hợp.
header.payload.signature
5

Ứng dụng khách hàng của chúng tôi

Bây giờ chúng tôi có máy chủ OAuth2 của chúng tôi, chúng tôi có thể tạo một ứng dụng khách để kiểm tra nó.

Điều này có thể có bất kỳ biểu mẫu nào bạn thích, đối với mẫu của tôi, tôi đã xây dựng một tập lệnh tệp đơn giản, đơn giản mà bạn có thể tìm thấy trong thư mục phụ

header.payload.signature
47 của dự án.

Khi người dùng muốn đăng nhập qua OAuth2, trước tiên họ được chuyển hướng đến điểm cuối

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
22 của máy chủ, với các tham số yêu cầu sau:
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    23 - Mã định danh máy khách
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    24 - URI để chuyển hướng người dùng sau khi họ đã đăng nhập / đồng ý
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    25 - Loại phản hồi, phải là
    Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    26
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    27 - phạm vi yêu cầu, đối với ứng dụng mẫu của tôi là
    Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    28.

Khách hàng cũng sẽ có điểm cuối

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
29, đó là những gì chúng tôi sẽ sử dụng làm
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
24 cho ứng dụng khách thử nghiệm của chúng tôi. Điểm cuối này sẽ nhận được tham số
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
26 mà chúng tôi có thể sử dụng để yêu cầu mã thông báo truy cập.

Chúng tôi làm điều này bằng cách gọi điểm cuối ____102 của máy chủ, với các tham số yêu cầu sau:

  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    23 - Mã định danh máy khách
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    24 - URI để chuyển hướng người dùng sau khi họ đã đăng nhập / đồng ý
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    24 - URI để chuyển hướng người dùng sau khi họ đã đăng nhập / đồng ý
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    25 - Loại phản hồi, phải là
    Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    26
  • Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    27 - phạm vi yêu cầu, đối với ứng dụng mẫu của tôi là
    Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    28.

Khách hàng cũng sẽ có điểm cuối

Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
29, đó là những gì chúng tôi sẽ sử dụng làm
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
24 cho ứng dụng khách thử nghiệm của chúng tôi. Điểm cuối này sẽ nhận được tham số
Header:
{
  "typ": "JWT",
  "alg": "RS256"
}
Payload:
{
  "aud": "testclient",
  "jti": "a4c3d9a9d6ac5ff1b5",
  "iat": 1662814887,
  "nbf": 1662814887,
  "exp": 1662818487,
  "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
  "scopes": [
    "blog_read",
    "profile",
    "email"
  ],
  "kid": "1",
  "custom": {
    "foo": "bar"
  }
}
Signature:
[Binary signature]
26 mà chúng tôi có thể sử dụng để yêu cầu mã thông báo truy cập.

Chúng tôi làm điều này bằng cách gọi điểm cuối ____102 của máy chủ, với các tham số yêu cầu sau:

$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password)); $server = new OAuth2\Server($storage); $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like! $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();04 - Bí mật của khách hàng

Trước khi chúng tôi có thể sử dụng ứng dụng máy khách của mình, chúng tôi cần tạo máy khách trên máy chủ OAuth2. Chúng tôi cũng sẽ cần tạo một tài khoản người dùng để đăng nhập.

Trong mẫu đầy đủ của tôi, tôi đã cung cấp một lệnh bootstrap trong ứng dụng máy chủ để thực hiện việc này.

header.payload.signature
6

Điều này sẽ tạo ra một máy khách với các chi tiết sau:

  • ID máy khách:
    $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
    12
  • Bí mật của khách hàng:
    $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
    13
  • Chuyển hướng URI:
    $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
    14
  • Phạm vi:
    Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    28
  • Tài trợ:
    $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
    16

Nó cũng sẽ tạo một người dùng với các chi tiết sau:

  • Tên người dùng:
    Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    2
  • Mật khẩu:
    Header:
    {
      "typ": "JWT",
      "alg": "RS256"
    }
    Payload:
    {
      "aud": "testclient",
      "jti": "a4c3d9a9d6ac5ff1b5",
      "iat": 1662814887,
      "nbf": 1662814887,
      "exp": 1662818487,
      "sub": "ac4fbaf2-30a5-11ed-94e9-09ec9787bcf6",
      "scopes": [
        "blog_read",
        "profile",
        "email"
      ],
      "kid": "1",
      "custom": {
        "foo": "bar"
      }
    }
    Signature:
    [Binary signature]
    3

Gói máy chủ OAuth2 League cũng cung cấp một số lệnh bảng điều khiển để giúp bạn tạo, cập nhật và xóa khách hàng mà bạn có thể đọc trong tài liệu của họ.

  • $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
    19
  • $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
    20
  • $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
    21
  • $storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    $server = new OAuth2\Server($storage);
    $server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
    $server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
    22

Thử nó ra

Bây giờ chúng tôi có thể dùng thử ứng dụng máy chủ và máy khách OAuth2 của chúng tôi.

Các hướng dẫn để quay lên máy chủ và máy khách có thể được tìm thấy trong readme của dự án mẫu trên repo github hoặc nếu bạn đã xây dựng dự án của riêng mình theo hướng dẫn này, bạn nên chạy ứng dụng máy chủ của mình thông qua web tích hợp Symfony Máy chủ hoặc máy chủ web cục bộ như Apache hoặc Nginx và chạy tập lệnh máy khách bằng máy chủ web tích hợp PHP hoặc máy chủ web cục bộ của bạn.

header.payload.signature
7

Trước tiên, chúng tôi muốn truy cập ứng dụng khách hàng của chúng tôi trong trình duyệt, bằng cách truy cập http: // localhost: 8080.

... sẽ đưa chúng tôi đến trang đăng nhập máy chủ, vì chúng tôi chưa đăng nhập.

... Chúng tôi đăng nhập với người dùng chúng tôi đã tạo trước đó.

... và chúng tôi được chuyển hướng đến trang đồng ý

... Nơi chúng ta có thể thấy các phạm vi mà chúng tôi đã yêu cầu và bất kỳ phạm vi hiện tại nào chúng tôi đã đồng ý. Chúng tôi chấp nhận sự đồng ý và được chuyển hướng trở lại ứng dụng máy khách.

... Và bây giờ chúng ta có thể gọi điểm cuối

$storage = new OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage)); // or any grant type you like!
$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
10 của máy chủ, sẽ trả về hồ sơ của người dùng.

Gói lên

Ứng dụng mẫu của tôi bị thiếu một vài phần chính mà bạn muốn đưa vào máy chủ OAuth2 trong thế giới thực.

  • Một cách để người dùng mới đăng ký.
  • Một cách để người dùng đặt lại mật khẩu của họ.
  • Một cách để người dùng quản lý và thu hồi các sự đồng ý hiện có.

Những mảnh này đều đủ tầm thường để bất kỳ ai quen thuộc với Symfony để thực hiện, vì vậy tôi đã bỏ chúng ra khỏi hướng dẫn.

Ngoài ra, mặc dù ứng dụng máy khách mẫu lưu trữ mã thông báo truy cập để thực hiện các yêu cầu API, nhưng nó không có bất kỳ logic nào để làm mới mã thông báo khi hết hạn. Tuy nhiên, máy chủ OAuth2 của chúng tôi bao gồm một loại tài trợ mã thông báo làm mới, do đó bạn có thể dễ dàng thêm điều này vào ứng dụng khách hàng của mình.

Đây là một bài viết khá dài để viết, hy vọng bạn thích nó và thấy nó hữu ích!


Bình luận

Tất cả các ý kiến ​​được điều chỉnh trước và sẽ không được công bố cho đến khi phê duyệt.

OAuth2 được sử dụng để làm gì?

OAuth 2.0, viết tắt của Ủy quyền mở, là một tiêu chuẩn được thiết kế để cho phép một trang web hoặc ứng dụng truy cập tài nguyên được lưu trữ bởi các ứng dụng web khác thay mặt cho người dùng.Nó đã thay thế OAuth 1.0 vào năm 2012 và hiện là tiêu chuẩn công nghiệp thực tế cho ủy quyền trực tuyến.allow a website or application to access resources hosted by other web apps on behalf of a user. It replaced OAuth 1.0 in 2012 and is now the de facto industry standard for online authorization.allow a website or application to access resources hosted by other web apps on behalf of a user. It replaced OAuth 1.0 in 2012 and is now the de facto industry standard for online authorization.

OAuth 2.0 trong API Web là gì?

OAuth 2.0 là một giao thức ủy quyền cung cấp cho máy khách API quyền truy cập giới hạn vào dữ liệu người dùng trên máy chủ web.API GitHub, Google và Facebook đáng chú ý sử dụng nó.an authorization protocol that gives an API client limited access to user data on a web server. GitHub, Google, and Facebook APIs notably use it.an authorization protocol that gives an API client limited access to user data on a web server. GitHub, Google, and Facebook APIs notably use it.

Làm thế nào sử dụng OAuth 2.0 cho các cuộc gọi API REST trong PHP?

Điều kiện tiên quyết duy nhất là PHP, nhà soạn nhạc và tài khoản nhà phát triển OKTA miễn phí ....

Tạo bộ xương API còn lại ..

Thực hiện phiên bản API REST ban đầu ..

Sử dụng Okta và OAuth 2.0 để bảo mật API ..

Thiết lập okta ..

Có được mã thông báo truy cập từ Okta ..

Thêm ủy quyền mã thông báo vào API ..

Thu hồi mã thông báo truy cập ..

OAuth có nghĩa là gì?

OAuth, viết tắt của ủy quyền mở, cho phép các dịch vụ của bên thứ ba trao đổi thông tin của bạn mà không cần phải cung cấp mật khẩu.Open Authorization,” allows third-party services to exchange your information without you having to give away your password.Open Authorization,” allows third-party services to exchange your information without you having to give away your password.