본문 바로가기

OAuth2 Server for PHP

OAuth2 서버를 만들기 위해 bshaffer 의 oauth2-server-php 코드를 사용한다.

https://github.com/bshaffer



요구사항

PHP 5.3.9 이상



설치

1
2
3
4
# git
$ git clone https://github.com/bshaffer/oauth2-server-php.git
# composer
$ composer.phar require bshaffer/oauth2-server-php "~1.8"
cs

(구조는 약간 틀리지만 composer 로 설치하여 테스트 하였다.)



Table 생성

* MySQL / SQLite / PostgreSQL / MS SQL Server

1
2
3
4
5
6
7
CREATE TABLE oauth_clients (client_id VARCHAR(80NOT NULL, client_secret VARCHAR(80), redirect_uri VARCHAR(2000NOT NULL, grant_types VARCHAR(80), scope VARCHAR(100), user_id VARCHAR(80), CONSTRAINT clients_client_id_pk PRIMARY KEY (client_id));
CREATE TABLE oauth_access_tokens (access_token VARCHAR(40NOT NULL, client_id VARCHAR(80NOT NULL, user_id VARCHAR(255), expires TIMESTAMP NOT NULL, scope VARCHAR(2000), CONSTRAINT access_token_pk PRIMARY KEY (access_token));
CREATE TABLE oauth_authorization_codes (authorization_code VARCHAR(40NOT NULL, client_id VARCHAR(80NOT NULL, user_id VARCHAR(255), redirect_uri VARCHAR(2000), expires TIMESTAMP NOT NULL, scope VARCHAR(2000), CONSTRAINT auth_code_pk PRIMARY KEY (authorization_code));
CREATE TABLE oauth_refresh_tokens (refresh_token VARCHAR(40NOT NULL, client_id VARCHAR(80NOT NULL, user_id VARCHAR(255), expires TIMESTAMP NOT NULL, scope VARCHAR(2000), CONSTRAINT refresh_token_pk PRIMARY KEY (refresh_token));
CREATE TABLE oauth_users (username VARCHAR(255NOT NULL, password VARCHAR(2000), first_name VARCHAR(255), last_name VARCHAR(255), CONSTRAINT username_pk PRIMARY KEY (username));
CREATE TABLE oauth_scopes (scope TEXT, is_default BOOLEAN);
CREATE TABLE oauth_jwt (client_id VARCHAR(80NOT NULL, subject VARCHAR(80), public_key VARCHAR(2000), CONSTRAINT jwt_client_id_pk PRIMARY KEY (client_id));
cs



기본 동작 구현


OAuth2 server Bootstrap

모든 엔드포인트로부터 사용될 OAuth2 server 객체를 생성하고 설정하는 부트스트랩 파일을 생성한다. (server.php)


Token Controller

클라이언트에게 OAuth2.0 토큰을 반환하는 토큰 컨트롤러 파일을 생성한다. (token.php)

임의로 DB 에 클라이언트 정보를 하나 삽입하고 curl 로 HTTP 요청을 하여 토큰 생성을 테스트할 수 있다.


DB 삽입

1
INSERT INTO oauth_clients (client_id, client_secret, redirect_uri) VALUES ("testclient""testpass""http://fake/");
cs


토큰 요청

1
2
$ curl -su testclient:testpass http://localhost/token.php -'grant_type=client_credentials'
{"access_token":"2577de35659f485b382d680edbba95356b595475","expires_in":3600,"token_type":"Bearer","scope":null}
cs

(호스트명은 localhost 라고 가정한다.)


Resource Controller

위에 생성된 토큰을 이용하여, 앞으로 만들 리소스나 API 에서 토큰의 유효성을 체크할 수 있다. (resource.php)


1
2
$ curl http://localhost/resource.php -'access_token=2577de35659f485b382d680edbba95356b595475'
{"success":true,"message":"You accessed my APIs!"}
cs


Authorize Controller

권한 부여 컨트롤러는 OAuth2 의 핵심 기능(killer feature)이며, 써드파티 어플리케이션에 사용자 권한을 부여할 수 있게 한다.

처음 토큰 컨트롤러 예제에서는 Access Token 이 즉시 발급되었지만, 권한 부여 컨트롤러는 사용자가 요청 권한을 가졌을 때 토큰을 발생하는데 사용한다. (authorize.php)


http://localhost/authorize.php?response_type=code&client_id=testclient&state=xyz


이 URL 을 브라우저에 입력하면 해당 해당 client_id 에게 권한을 부여할 것인지를 묻는 프롬프트 폼이 보여진다.

'예'를 클릭하면 발급된 Authorization Code 를 확인할 수 있다.


SUCCESS! Authorization Code: 097e3c941d91a84861fef771c025cbb365dff010


이제 미리 만들어놓은 토큰 컨트롤러에서 Authorization Code 로 Access Token 을 발급받을 수 있다.

1
2
$ curl -u testclient:testpass http://localhost/token.php -'grant_type=authorization_code&code=097e3c941d91a84861fef771c025cbb365dff010'
{"access_token":"1bde0a7785f78eaddcd3e4555ca382e884d9ad4f","expires_in":3600,"token_type":"Bearer","scope":null,"refresh_token":"c8d988fdcf8707f5e8f728a86aa0e49d3109b9b0"}
cs

Authorization Code 는 발급 후 30초 뒤에 만료된다.


Associating Local Users With Access Tokens

사용자 권한을 인증하고 access token 을 발급하면, 토큰을 사용한 사용자가 누구인지 알고 싶을 것이다.

handleAuthorizeRequest 메소드의 파라미터에 user_id 를 사용하면 사용자를 알 수 있다.


1
2
3
<?
$userid = 1234// A value on your server that identifies the user
$server->handleAuthorizeRequest($request$response$is_authorized$userid);
cs


사용자 ID 는 access token 과 함께 DB 에 저장될 것이다.

이 토큰이 클라이언트로부터 사용되면 할당된 ID 를 검색할 수 있다.


1
2
3
4
5
6
7
8
<?
if (!$server->verifyResourceRequest(OAuth2\Request::createFromGlobals())) {
    $server->getResponse()->send();
    die;
}
 
$token = $server->getAccessTokenData(OAuth2\Request::createFromGlobals());
echo "User ID associated with this token is {$token['user_id']}";
cs