Integracja aplikacji Ruby on Rails 3 z platformą GGAPI
W dzisiejszym gościnnym wpisie Marcin 'Martio' Lewandowski opisze sposób integracji aplikacji RoR z platformą GGAPI:
Do zintegrowania aplikacji Rails'owej z platformą Gadu-Gadu zastosujemy uniwersalny i elastyczny system uwierzytelniania z wykorzystaniem Rack Middleware o nazwie OmniAuth (https://github.com/intridea/omniauth).
Zaczynamy od zainstalowania niezbędnych gem-ów. W pliku Gemfile dodajemy dwa nowe gem-y:
gem 'oauth2' gem 'omniauth'
i wykonujemy polecenie `bundle install`.
Kiedy posiadamy już niezbędne biblioteki w naszej aplikacji możemy przystąpić do integracji i właściwej konfiguracji adaptera OmniAuth. Biblioteka ta wprawdzie nie posiada w standardowym wydaniu adaptera strategii uwierzytelniania dla Gadu-Gadu, ale takowy znajdziemy również na Github-ie pod adresem: https://gist.github.com/8e82aabe6de2cb090121.
Klonujemy plik adaptera będąc w katalogu `lib` poleceniem
git clone git@gist.github.com:8e82aabe6de2cb090121.git
lub ściągamy ręcznie z podanej strony. Adapter przystosowany jest do biblioteki OmniAuth w wersji 0.1.6.
Konfiguracja jest banalnie prosta i polega na dodaniu nowego inicjatora. Tworzymy nowy
plik `config/initializers/omniauth.rb` o następującej zawartości:
module OmniAuth module Strategies autoload :GG, 'gg_omniauth_strategy' end end Rails.application.config.middleware.use OmniAuth::Builder do provider :GG, CLIENT_ID, CLIENT_SECRET end
W ten oto prosty i szybki sposób zintegrowaliśmy naszą aplikację z platformą Gadu-Gadu. Dla pełnej satysfakcji brakuje nam jeszcze kontrolera, który obsłuży zautoryzowanych użytkowników GG.
Dodajemy dwie nowe trasy do konfiguracji routingu w pliku `config/routes.rb`:
match '/auth/:provider/callback' => 'authentications#create' match '/auth/failure' => 'authentications#failure'
Ostatnim krokiem jest utworzenie kontrolera `app/controllers/authentications_controller.rb`:
class AuthenticationsController < ApplicationController rescue_from User::NotAuthorized, :with => :user_not_authorized def create omniauth = request.env['omniauth.auth'] raise User::NotAuthorized unless omniauth['uid'] user = User.find_by_uid(omniauth['uid']) unless user user = User.new user.uid = omniauth['uid'] user.name = omniauth['user_info'][(!omniauth['user_info']['nickname'].empty? ? 'nickname' : 'name')] user.picture = "http://avatars.gg.pl/#{omniauth['uid']}" raise User::NotAuthorized unless user.save end session['uid'] = user.id session['token'] = omniauth['credentials']['token'] redirect_to_after_authentication end def failure user_not_authorized end protected def redirect_to_after_authentication render :text => "<script type='text/javascript' charset='utf-8'>top.location.href = 'http://www.gg.pl/#apps/MY_APP';</script>" end def user_not_authorized render :text => '401 Unauthorized', :status => 401 end end
Podczas uwierzytelnienia zachowaliśmy w sesji access_token, który wykorzystujemy do autoryzacji dostępu do API. Teraz pobranie np. listy kontaktów zautoryzowanego użytkownika to nic prostszego. Wystarczy tylko skorzystać z klienta OAuth2:
@client = OAuth2::Client.new(CLIENT_ID, CLIENT_SECRET, :parse_json => true) @token = OAuth2::AccessToken.new(@client, session['token']) result = @token.get('https://users.api.gg.pl/friends/me', {:limit => 1000}, {'Accept-Charset' => 'ISO-8859-2,utf-8;q=0.7,*;q=0.7'})
Na koniec jeszcze jedna bardzo ważna uwaga. Uwierzytelnienie w bibliotece OmniAuth następuje po przekierowaniu użytkownika na URL `/auth/gg`. Jako, że w panelu administracyjnym aplikacji nie możemy ustawić tego typu URL-a celem ustandaryzowania automatycznego przekierowania użytkownika do procesu uwierzytelnienia jego dostępu do naszej aplikacji, możemy zastosować pewien trick używając ponownie Rack Middleware.
Tworzymy klasę odpowiedzialną za wykrycie żądania pochodzącego z platformy Gadu-Gadu `lib/detect_platform.rb`:
class DetectPlatform def initialize(app) @app = app end def call(env) request = Rack::Request.new(env) if request.params['gg_session_id'] request.env[:request_comes_from_platform] = :gg end @app.call(env) end end
i rejestrujemy ją w utworzonym wcześniej inicjatorze:
require 'detect_platform' Rails.application.config.middleware.use DetectPlatform
Od teraz możemy wykryć w głównym kontrolerze czy żądanie pochodzi z platformy Gadu-Gadu i w razie takiej potrzeby przekierować użytkownika do systemu uwierzytelnienia.
class HomeController < ApplicationController before_filter :check_authorization def show end private def check_authorization render :text => '403 Forbidden', :status => 403 unless request.env[:request_comes_from_platform] render :text => "<script type='text/javascript' charset='utf-8'>top.location.href = '#{request.protocol}#{request.host_with_port}/auth/gg';</script>" unless session['uid'] end end
Ostatnie Komentarze