Module: LineAct

Defined in:
lib/line_act.rb,
lib/line_act/version.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =
"0.1.3"

Class Method Summary collapse

Class Method Details

.access_token_check(req) ⇒ Object



124
125
126
127
128
129
130
131
132
# File 'lib/line_act.rb', line 124

def self.access_token_check(req)
  HtReq.get_json_data({
    :url=>'https://api.line.me/oauth2/v2.1/verify',
    :method=>'GET',
    :params=>{
      :access_token=>req.session[:line_act_access_token]
    }
  })
end

.basic_test(req, controller, user, access_log) ⇒ Object



65
66
67
68
69
70
71
72
73
# File 'lib/line_act.rb', line 65

def self.basic_test(req,controller,user,access_log)
  #環境変数の存在チェック
  ENV['LINE_CLIENT_ID'].nil? ? @error.push('環境変数LINE_CLIENT_IDが存在しません'):nil
  ENV['LINE_REDIRECT_URL'].nil? ? @error.push('環境変数LINE_REDIRECT_URLが存在しません'):nil
  ENV['LINE_SECRET'].nil? ? @error.push('環境変数LINE_SECRETが存在しません'):nil
  ENV['LINE_SCOPE'].nil? ? @error.push('環境変数LINE_SCOPEが存在しません'):nil
  #ログインページの問題確認
  @error.push('ログインページへのURLに問題がある可能性があります') unless HtReq.request({:url=>self.(req)}).code == '302'
end

.case_first_contact(req, user, access_log) ⇒ Object



98
99
100
101
102
103
104
105
# File 'lib/line_act.rb', line 98

def self.case_first_contact(req,user,access_log)
  if self.get_first_access_token(req)
    if self.(req)
      self.(req,user)
      self.set_access_log(req,user,access_log)
    end
  end
end

.case_have_access_token(req, user, access_log) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/line_act.rb', line 107

def self.case_have_access_token(req,user,access_log)
  if self.has_access_token(req)
    if self.access_token_check(req)
      self.set_access_log(req,user,access_log)
    else
      self.user_sign_out(req)
    end
  end
end

.get_access_token(code) ⇒ Object

トークンを取得する



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/line_act.rb', line 202

def self.get_access_token(code)
  HtReq.get_json_data({
    :url=>'https://api.line.me/oauth2/v2.1/token',
    :method=>'POST',
    :params=>{
      :grant_type=>'authorization_code',
      :code=>code,
      :redirect_uri=>ENV['LINE_REDIRECT_URL'],
      :client_id=>ENV['LINE_CLIENT_ID'],
      :client_secret=>ENV['LINE_SECRET']
    },
    :header=>{
      "Content-Type":"application/x-www-form-urlencoded"
    }
  })
end

.get_errors(req) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/line_act.rb', line 76

def self.get_errors(req)
  req.session[:line_act_errors]=''
  @error.each do |e|
    req.session[:line_act_errors]+e
  end
  @error=[]
  nil
end

.get_first_access_token(req) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/line_act.rb', line 182

def self.get_first_access_token(req)
   if req.session[:line_act_access_token].nil? && req.params[:state] && req.params[:code]
      #トークンのチェック
      if req.params[:state]==req.session[:line_act_state]
          if res = self.get_access_token(req.params[:code])
             req.session[:line_act_access_token]=res["access_token"] 
             req.session[:line_act_refresh_token]=res["refresh_token"]
             req.session[:line_act_id_token]=res["id_token"]
             return true
          else
            @error.push('トークンが一致しません。(state)')
            return false
          end
      end
   end
   return false
end

.get_first_user_info(req) ⇒ Object



159
160
161
162
163
164
165
166
167
168
# File 'lib/line_act.rb', line 159

def self.(req)
    if res = self.(req.session[:line_act_id_token])
        req.session[:line_act_name] = res["name"]
        req.session[:line_act_picture]= res["picture"].blank? ? '':res["picture"]
        req.session[:line_act_sub]=res["sub"]
        return true
    end
    @error.push('id_tokenからユーザー情報を取得できませんでした')
    return false
end

.get_login_url(req) ⇒ Object

ログインURLとcsrf_tokenを取得する



220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/line_act.rb', line 220

def self.(req)
  req.session[:line_act_state] = SecureRandom.hex(10)
  HtReq.set_get_params_to_url('https://access.line.me/oauth2/v2.1/authorize',
    {
      :response_type=>'code',
      :client_id=>ENV['LINE_CLIENT_ID'],
      :redirect_uri=>ENV['LINE_REDIRECT_URL'],
      :state=>req.session[:line_act_state],
      :scope=>ENV['LINE_SCOPE'],
      :bot_prompt=>'aggressive'
    }).to_s
end

.get_user_info(id_token) ⇒ Object



170
171
172
173
174
175
176
177
178
179
# File 'lib/line_act.rb', line 170

def self.(id_token)
  HtReq.get_json_data({
    :url=>'https://api.line.me/oauth2/v2.1/verify',
    :method=>'POST',
    :params=>{
      :id_token=>id_token,
      :client_id=>ENV['LINE_CLIENT_ID'],
    }
  })
end

.has_access_token(req) ⇒ Object



134
135
136
# File 'lib/line_act.rb', line 134

def self.has_access_token(req)
  req.session[:line_act_access_token].present? 
end

.helpObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/line_act.rb', line 17

def self.help
  puts <<'EOF'
##################このGemの使い方######################
環境変数に下記のものを設定しておくこと。
LINE_CLIENT_ID・・・Line DeveloperコンソールでログインAPIのクライアントIDを確認
LINE_REDIRECT_URL・・・Line Developerコンソールで設定したリダイレクト用のURL
LINE_SCOPE・・・Line Login APIに問い合わせる内容。
LINE_SECRET・・・Line Developerコンソールで設定したシークレットキー
他にもユーザーテーブル(LineUser)とアクセスログテーブル(AccessLog)を設定する

使い方としてはリダイレクト先のコントローラーで
LineAct.profile_action(@_request,self,LineUser,AccessLog)
というふうに定義する

サインアウト処理は
LineAct.user_sign_out(@_request)
とでも書いておいて、あとはcurrent_userをnilにするなり、どこかにリダイレクトするなり


テーブル設計はこんな感じ
テーブル名:line_users
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| line_id      | varchar(255) | YES  |     | NULL    |                |
| display_name | varchar(255) | YES  |     | NULL    |                |
| picture      | varchar(255) | YES  |     | NULL    |                |
| admin        | tinyint(1)   | YES  |     | 0       |                |
| created_at   | datetime(6)  | NO   |     | NULL    |                |
| updated_at   | datetime(6)  | NO   |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

access_logs
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| line_user_id | bigint(20)   | NO   | MUL | NULL    |                |
| ip           | varchar(255) | YES  |     | NULL    |                |
| created_at   | datetime(6)  | NO   |     | NULL    |                |
| updated_at   | datetime(6)  | NO   |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

#######################################################
EOF
end

.insert_user_info(req, user) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/line_act.rb', line 142

def self.(req,user)
    #ユーザーが既に存在しなければ
    if user.find_by(:line_id=>req.session[:sub]).blank?
      #最初のユーザーであれば
      if user.all.count == 0
        user.create(:line_id=>req.session[:line_act_sub],:display_name=>req.session[:line_act_name],:picture=>req.session[:line_act_picture],:admin=>true)
      else
        user.create(:line_id=>req.session[:line_act_sub],:display_name=>req.session[:line_act_name],:picture=>req.session[:line_act_picture])
      end
    else
      #アップデートする
      user.find_by(:line_id=>req.session[:line_act_sub]).update(:line_id=>req.session[:line_act_sub],:display_name=>req.session[:line_act_name],:picture=>req.session[:line_act_picture])
    end
end

.profile_action(req, controller, user, access_log) ⇒ Object



87
88
89
90
91
92
93
94
95
96
# File 'lib/line_act.rb', line 87

def self.profile_action(req,controller,user,access_log)
  self.case_have_access_token(req,user,access_log)
  self.case_first_contact(req,user,access_log)
  if req.session[:line_act_access_token].nil?
    controller.redirect_to self.(req) and return
  end
  #エラーの取得
  self.basic_test(req,controller,user,access_log)
  self.get_errors(req)
end

.set_access_log(req, user, access_log) ⇒ Object



138
139
140
# File 'lib/line_act.rb', line 138

def self.set_access_log(req,user,access_log)
   access_log.create(:line_user_id=>user.find_by(:line_id=>req.session[:line_act_sub]).id,:ip=>req.remote_ip) 
end

.user_sign_out(req) ⇒ Object



118
119
120
121
122
# File 'lib/line_act.rb', line 118

def self.user_sign_out(req)
  req.session.each do |k,v|
    req.session[k]=nil
  end
end