2017/01/17

[Python][Google App Engine][Twitter][OAuth]request token

昔、書いた[Google App Engine][twitter][oauth]ログインを自作するから少し仕様が変わったみたいなので、少し見やすくして、新しくクラスを作ってみた。
//twitter.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from google.appengine.api import urlfetch
import datetime
import time
import random
import urllib
import hmac
import hashlib
import logging

class LoginTwitter(object):
    def __init__(self,consumer_secret,consumer_key,oauth_callback_url):
        self.consumer_secret = consumer_secret
        self.method = "POST"
        self.request_token_url = "https://api.twitter.com/oauth/request_token"
        self.oauth_authenticate_url = "https://api.twitter.com/oauth/authenticate"
        self.prms = {
            "oauth_consumer_key":consumer_key,
            "oauth_nonce":LoginTwitter._nonce(),
            "oauth_signature_method":'HMAC-SHA1',
            "oauth_version":'1.0',
            "oauth_timestamp":LoginTwitter._timeStamp(),
            "oauth_callback":oauth_callback_url
        }

        self.prms['oauth_signature'] = self._signature()
        self._request()

    @classmethod
    def _timeStamp(cls):
        _d = datetime.datetime.today()
        _d = time.mktime(_d.timetuple())
        _d = str(int(_d))
        return _d

    @classmethod
    def _nonce(cls):
        _s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789[]{}!$%&'()-^\:;*+><"
        _l = list(_s)
        _n = ""
        for i in range(20):
            _x = random.randint(0,len(_l)-1)
            _n += _l[_x]
        return _n

    def _signature(self):
        _prms_keys = sorted(self.prms.keys())
        _prms = ''
        for i in _prms_keys:
            _prms = _prms + "&" + i + "=" + urllib.quote_plus(self.prms[i])
        else:
            _prms = _prms[1:]

        _prms = urllib.quote_plus(self.method) + "&" + urllib.quote_plus(self.request_token_url) + "&" + urllib.quote_plus(_prms)
        _h = hmac.new("%s&%s" % (urllib.quote(self.consumer_secret), urllib.quote("")), _prms, hashlib.sha1)
        _sig = _h.digest().encode("base64").strip()
        return _sig

    def _request(self):
        
        if self.method == 'POST':
            _headers = {
                'Content-Type': 'application/x-www-form-urlencoded'
            }

            _prms_keys = sorted(self.prms.keys())
            _prms = ''
            for i in _prms_keys:
                _prms = _prms + "," + i + "=\"" + urllib.quote_plus(self.prms[i]) + "\""
            else:
                _prms = _prms[1:]

            _prms = "OAuth " + _prms
            _headers["Authorization"] = _prms
            _result = urlfetch.fetch(
                url = self.request_token_url,
                payload = urllib.urlencode({"oauth_callback":self.prms["oauth_callback"]}),
                method = urlfetch.POST,
                headers = _headers
            )
            logging.info(_result.status_code)
            logging.info(_result.content)
呼び出しはいたって簡単。
from twitter import LoginTwitter
consumer_secret
consumer_key
oauth_callback_url
LoginTwitter(consumer_secret,consumer_key,oauth_callback_url)
まだ全部の処理が書き終わっていないので、改訂が入るかも。

0 コメント:

コメントを投稿