[Line Login] Integrate Line Login with Rails 4
Recently I got a task to create a website with Line Login feature. This feature allows users to login with their Line account to 3rd party websites by using OAuth2.0.
After user login and grant privileges to 3rd party website, Line will provide following user information:
- User’s nickname
- User’s ID
- User’s profile image URL
- User’s statue message
{
"displayName":"Brown",
"mid":"u0047556f2e40dba2456887320ba7c76d",
"pictureUrl":"http://example.com/abcdefghijklmn",
"statusMessage":"Hello, LINE!"
}
and the pictureUrl supports 2 sizes:
# Profile image thumbnails
200x200: http://example.com/abcdefghijklmn/large
51x51: http://example.com/abcdefghijklmn/small
Line’s developer site suggest to implement Line Login with following steps:
- Create a business account at the Business Center
- Select LINE Login on your business account page
- Create a Channel
- Integrate LINE’s user authentication process into website
- Use REST APIs from website
- Test website
- Publish website
The most important steps should be step 4, and here’s how I implemented it with Rails 4
Framework
- Ruby on Rails
- Ruby: 2.2.5
- Rails: 4.2.7
- Gems: omniauth-line
MVC
- User model
- Stores user information after authentication & authorization
- Pages controller
- index action
- render view
- index action
- Sessions controller
- create action
- login
- Uses Omniauth to get user data from Line
- destroy action
- logout
- create action
- Index view
- Display welcome message and button to login
- Display user profile after login
How to integrate
Line channel configuration:
-
Add production callback url, the link should look like this:
# https is mandatory <https://example.com/auth/line/callback>
Rails configuration:
-
Install
omniauth-linegemgem install omniauth-line -
Configure provider information
#config/initializers/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :line, ENV['CHANNEL_ID'], ENV['CHANNEL_SECRET'] end OmniAuth.config.on_failure = Proc.new do |env| SessionsController.action(:action_failure).call(env) end -
Configure routes for callback and logout
Rails.application.routes.draw do root 'pages#index' get '/auth/:provider/callback', to: 'sessions#create' delete '/logout', to: 'sessions#destroy' end -
Configure Sessions Controller for create, destroy action
def create begin @user = User.from_omniauth(request.env['omniauth.auth']) session[:user_id] = @user.id flash[:success] = "Welcome, #{@user.username}!" rescue flash[:warning] = "There was an error occured..." end redirect_to root_path end def destroy if current_user session.delete(:user_id) flash[:success] = 'Ciao!' end redirect_to root_path end def auth_failure redirect_to root_path end -
Generate migration file to store user data
create_table :users do |t| t.string :provider, null: false t.string :uid, null: false t.string :access_token t.string :username t.string :image_url t.string :status_msg t.timestamps null: false end add_index :users, :provider add_index :users, :uid add_index :users, [:provider, :uid], unique: true -
Configure user.rb to save user data
class << self def from_omniauth(auth_hash) user = find_or_create_by(uid: auth_hash['uid'], provider: auth_hash['provider']) user.username = auth_hash['info']['name'] user.image_url = auth_hash['info']['image'] user.status_msg = auth_hash['info']['description'] user.access_token = auth_hash['credentials']['token'] user.save! user end end -
Configure views to display user info after user login
all the works should be done by now!
Note:
Sometimes Line Login service is not stable, you may encountered issues to login, or not redirecting after login, if you’re sure the callback url you configure is correct, maybe Line service is down.