Dancer-Plugin-Auth-Github
view release on metacpan or search on metacpan
lib/Dancer/Plugin/Auth/Github.pm view on Meta::CPAN
our $VERSION = '0.04';
my $client_id;
my $client_secret;
my $scope = "";
my $github_redirect_url = 'https://github.com/login/oauth/authorize/';
my $github_post_url = 'https://github.com/login/oauth/access_token/';
my $github_auth_failed = '/auth/github/failed';
my $github_auth_success = '/';
my $state_salt = "RandomSalt";
#A method to initializa everything
register 'auth_github_init' => sub {
my $config = plugin_setting;
$client_id = $config->{client_id};
$client_secret = $config->{client_secret};
for my $param (qw/client_id client_secret/) {
croak "'$param' is expected but not found in configuration"
unless $config->{$param};
}
#sthe following configs are optional.
if($config->{scope}) {
$scope = $config->{scope};
}
#these configs have default values.
if($config->{github_auth_failed})
{
$github_auth_failed = $config->{github_auth_failed};
}
if($config->{github_auth_success})
{
$github_auth_success = $config->{github_auth_success};
}
debug 'Loaded config..';
};
#returns the url you need to redirect to to authenticate on github
register 'auth_github_authenticate_url' => sub {
my $generate_state = sha256_hex($client_id.$client_secret.$state_salt);
return "$github_redirect_url?&client_id=$client_id&scope=$scope&state=$generate_state";
};
#registers this as a callback url
get '/auth/github/callback' => sub {
my $generate_state = sha256_hex($client_id.$client_secret.$state_salt);
my $state_received = params->{'state'};
if($state_received eq $generate_state) {
my $code = params->{'code'};
my $browser = LWP::UserAgent->new;
my $resp = $browser->post($github_post_url,
[
client_id => $client_id,
client_secret => $client_secret,
code => $code,
state => $state_received
]);
die "error while fetching: ", $resp->status_line
unless $resp->is_success;
my %querystr = parse_query_str($resp->decoded_content);
my $acc = $querystr{access_token};
if($acc) {
my $jresp = $browser->get("https://api.github.com/user?access_token=$acc");
my $json = decode_json($jresp->decoded_content);
session 'github_user' => $json;
session 'github_access_token' => $acc;
#session 'logged_in' => true;
redirect $github_auth_success;
return;
}
}
redirect $github_auth_failed;
};
#helper method to parse query string.
sub parse_query_str {
my $str = shift;
my %in = ();
if (length ($str) > 0){
my $buffer = $str;
my @pairs = split(/&/, $buffer);
foreach my $pair (@pairs){
my ($name, $value) = split(/=/, $pair);
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$in{$name} = $value;
}
}
return %in;
}
register_plugin;
1; # End of Dancer::Plugin::Auth::Github
__END__
=head1 NAME
Dancer::Plugin::Auth::Github - Authenticate with Github
=head1 SYNOPSIS
package YourDancerApplication;
use Dancer ':syntax';
use Dancer::Plugin::Auth::Github;
#You must use a session backend.
#You should be able to use any backend support by dancer.
set 'session' => 'Simple';
#make sure you call this first.
#initializes the config
auth_github_init();
hook before => sub {
#we don't want to be in a redirect loop
return if request->path =~ m{/auth/github/callback};
if (not session('github_user')) {
redirect auth_github_authenticate_url;
}
};
#by default success will redirect to this route
get '/' => sub {
"Hello, ".session('github_user')->{'login'};
#For all the github_user properties
( run in 1.798 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )