python-oauth2实现开放接口

已经不想写java了,python操作起来不用担心什么服务都搞个100多M,只是网上的资料并不多,写脚本就能提供接口,是不是很轻量?

pip install sqlalchemy -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install tornado -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install python-oauth2 -i https://pypi.tuna.tsinghua.edu.cn/simple

服务端定义

from tornado import web, httpserver, ioloop
from controller import OrderHandler,TokenHandler
from oauth2 import Provider
from oauth2.grant import ClientCredentialsGrant,RefreshToken
from oauth2.tokengenerator import Uuid4
from oauth2.store.redisdb import TokenStore
from oauth2.store.memory import ClientStore
from settings import API_CONFIG,ENV,REDIS_CONFIG

def run_app_server():
    client_store = ClientStore()
    client_store.add_client(client_id=API_CONFIG['sc']['client_id'],client_secret=API_CONFIG['sc']['client_secret'],redirect_uris="")
    token_store = TokenStore(host=REDIS_CONFIG[ENV]['host'],port=REDIS_CONFIG[ENV]['port'], db=REDIS_CONFIG[ENV]['db'])
    generator = Uuid4()
    generator.expires_in = {'client_credentials':API_CONFIG['api']['token']}
    provider = Provider(access_token_store=token_store,auth_code_store=token_store,client_store=client_store
                        ,token_generator=generator)
    provider.add_grant(ClientCredentialsGrant())
    try:
        app = web.Application([
            (r"/kkd/order/add",OrderHandler),
            web.url(provider.authorize_path,TokenHandler,dict(provider=provider)),
            web.url(provider.token_path,TokenHandler,dict(provider=provider)),
        ])
        httpServer = httpserver.HTTPServer(app)
        httpServer.listen(8000)
        ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        ioloop.IOLoop.close()

扩展一下返回参数,这个python-oauth2写的还是有些粗糙

class TokenHandler(OAuth2Handler):

    def post(self):
        response = self._dispatch_request()
        for name, value in list(response.headers.items()):
            self.set_header(name, value)
        body = json.loads(response.body)
        if 'access_token' in body:
            resp = {'success':True,'code':'0000','timestamp':int(str(time.time()*1000).split('.')[0])}
            resp['data'] = {
                'access_token':body['access_token'],
                'token_type':body['token_type'],
                'expires_in':10000
            }
        else:
            resp = {'success':False,'code':'0003','msg':'认证失败'}
        self.write(json.dumps(resp, ensure_ascii=False))
        self.set_status(response.status_code)

再业务中,从redis中获取token

 def check_token(self):
        '''
        检查token
        '''
        access_token = token_store.fetch_existing_token_of_user(client_id=API_CONFIG['sc']['client_id'],grant_type="client_credentials",user_id=None)
        token = self.request.headers.get('Authorization')
        if token == 'Bearer '+access_token.token:
            return None
        else:
            return 'token认证失败'

python-oauth2这个里面是bug的,数据写入到redis中,没有过期时间,改两个地方就可以了
oauth2.store.redisdb.TokenStore,过期时间写在数据里面有什么用的,永远不会清楚,除非自己写定时任务

def save_token(self, access_token):
        """
        Stores the access token and additional data in redis.

        See :class:`oauth2.store.AccessTokenStore`.

        """
        self.write(access_token.token, access_token) # edit bj dzm 去掉__dict__

        unique_token_key = self._unique_token_key(access_token.client_id,
                                                  access_token.grant_type,
                                                  access_token.user_id)
        self.write(unique_token_key, access_token) # edit bj dzm 去掉__dict__

        if access_token.refresh_token is not None:
            self.write(access_token.refresh_token, access_token.__dict__)
def write(self, name, data):
        cache_key = self._generate_cache_key(name)
        self.rs.set(cache_key, json.dumps(data.__dict__),ex=data.expires_in) # edit by dzm

1
在centos环境下安装python-oauth2报错

Collecting python-oauth2
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/09/30/fae66a452716f49b69124c9286ba48719ae62014a1f97bcf269c88c0c0d3/python-oauth2-1.1.1.tar.gz (45 kB)
     |████████████████████████████████| 45 kB 2.0 MB/s 
    ERROR: Command errored out with exit status 1:
     command: /usr/local/python3/bin/python3.8 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-reexv8iu/python-oauth2/setup.py'"'"'; __file__='"'"'/tmp/pip-install-reexv8iu/python-oauth2/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-8j99t6z6
         cwd: /tmp/pip-install-reexv8iu/python-oauth2/
    Complete output (11 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/usr/local/python3/lib/python3.8/site-packages/setuptools/__init__.py", line 23, in <module>
        from setuptools.dist import Distribution
      File "/usr/local/python3/lib/python3.8/site-packages/setuptools/dist.py", line 34, in <module>
        from setuptools import windows_support
      File "/usr/local/python3/lib/python3.8/site-packages/setuptools/windows_support.py", line 2, in <module>
        import ctypes
      File "/usr/local/python3/lib/python3.8/ctypes/__init__.py", line 7, in <module>
        from _ctypes import Union, Structure, Array
    ModuleNotFoundError: No module named '_ctypes'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

需要yum install libffi-devel -y,重新安装python

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值