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 priveleges to 3rd party website, Line will provide following user information:

  1. User’s nickname
  2. User’s ID
  3. User’s profile image URL
  4. 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:

  1. Create a business account at the Business Center
  2. Select LINE Login on your business account page
  3. Create a Channel
  4. Integrate LINE’s user authentication process into website
  5. Use REST APIs from website
  6. Test website
  7. Publish website

The most important steps should be step 4, and here’s how I implemented it with Rails 4

Framwork

MVC

  • User model
    • Stores user infomation after authentiation & authorization
  • Pages controller
    • index action
      • render view
  • Sessions controller
    • create action
      • login
      • Uses Omniauth to get user data from Line
    • destroy action
      • logout
  • 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://example.com/auth/line/callback
  #https is mandatory
  

Rails configuration:

  • Install ‘omniauth-line’ gem
  $gem install omniauth-line
  
  • Configure provider infomation
  #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.

My sample repo