Jeen - Yet anothere techlog

STFUAWSC

Using Plack::Middleware::OAuth

Before Using Plack::Middleware::OAuth

사실은 Plack::Middleware::OAuth 를 사용하기 이전에는 OAuth 관련 callback 처리등을 직접 파라메터를 확인해가면서 해당 액션을 처리했었습니다. 그게 P::M::OAuth 를 사용해서 각 OAuth Provider 들을 좀 더 유연하게 다룰 수 있게 되지 않았나 합니다.

~~~ perl

sub redirect_to_foursquare {
    my $self = shift;

    # redirect to foursquare authentication url
    $self->response->redirect("https://foursquare.com/oauth2/authenticate?client_id=$client_id&response_type=code&redirect_uri=$callback_url");
}

sub receive_token_foursquare {

  my $self = shift;

  my $res = Furl->new->get("https://foursquare.com/oauth2/access_token?client_id=$client_id&client_secret=$client_secret&grant_type=authorization_code&redirect_uri=$redirect_url&code=".$self->request->param('code'));
  ...

} ~~~

예, 뭐 위처럼 OAuth 인증시에 client_idclient_secret 그리고 grant_type 등 여러가지 파라메터의 지정이나 인증 URL 등등이 Provider 마다 다르고 이러니 뭐 일일이 Provider 마다 매번 어플리케이션 단에서 코드를 써나가는 것이 참 불쾌하기 마련이었습니다.

나름 플러거블하게 만든다고 해봤지만 역시 이런 부분은 Middleware 단에서 처리하는 게 좋지 않을까 생각하고 있었지요. 그런의미에서 P::M::OAuth 를 사용하게 되었습니다.

Custom Provider

P::M::OAuth 는 OAuth v1/v2 를 지원합니다. OAuth 버젼마다 파라메터가 바뀌기 때문에 사용하고자 하는 OAuth Provider 가 어떤 버젼을 지원하는 지 확인해봐야 합니다.

P::M::OAuth 는 기본적으로 Github, Twitter, Facebook, Live, Google 의 다섯가지 OAuth Provider 를 지원합니다.

저는 FourSquare 의 OAuth 를 사용하려고 하는 데, 기본적으로 제공해주지 않으니, 약간 손질을 해줘야 되겠죠.

~~~ perl package Plack::Middleware::OAuth::Foursquare; use strict; use warnings;

sub config {

+{
    version          => 2,
    authorize_url    => 'https://foursquare.com/oauth2/authenticate',
    access_token_url => 'https://foursquare.com/oauth2/access_token',
    response_type    => 'code',
    grant_type       => 'authorization_code',
};

}

1; ~~~

위처럼 Plack::Middleware::OAuth::Foursquare 와,

~~~ perl package Plack::Middleware::OAuth::UserInfo::Foursquare; use strict; use warnings; use parent qw(Plack::Middleware::OAuth::UserInfo); use LWP::UserAgent; use JSON;

sub create_handle {}

sub query {

my $self = shift;

my $uri = URI->new('https://api.foursquare.com/v2/users/self');
$uri->query_form( oauth_token => $self->token->access_token );
my $res = LWP::UserAgent->new->get($uri);
my $body = $res->decoded_content;
return unless $body;

my $obj = decode_json($body) || {};
return $obj->{response}->{user};

}

1; ~~~

Plack::Middleware::OAuth::UserInfo::Foursquare 를 추가합니다.

이렇게 쉽게 OAuth Provider 마다 해당 네임스페이스 맞는 모듈을 추가해줍니다.

MyApp

~~~ perl

my $app = MyApp->psgi_app; builder {

mount '/oauth' => builder {
    enable 'OAuth',
        on_success => sub {
            my ($mw, $token) = @_;

            # get Foursquare's UserInfo
            my $info = Plack::Middleware::OAuth::UserInfo->new( config => $mw->config, token => $token );

            if ($token->is_provider('Foursquare')) {
            return $mw->redirect('/');  
          }
          on_error => sub { #... },
          providers => {
              'Foursquare' => {
                  client_id => 'YOUR CLIENT_ID',
                  client_secret => 'YOUR CLIENT_SECRET',
              },
          };
        }
};
mount '/' => $app;

}; ~~~

대충 위처럼 사용을 합니다. 좀 더 자세한 예제는 P::M::OAuth 모듈의 예제 psgi 파일 또는 , 이 모듈을 사용한 제 프로젝트 Bobby-Akawa 의 특정 모듈에서 찾아볼 수 있습니다.

Conclusion

이로써 간략하게나마 Plack::Middleware::OAuth 를 이용해서 OAuth 인증을 Plack Middleware 단에서 구현할 수 있게 되었습니다. 조금 설명이 빈약해서 차후에 좀 더 구현단으로 들어가서 좀 더 깊게 파고들어가 볼까 합니다.

Comments