• 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
    
    • 1
    • 2
    • 3

    服务端定义

    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    扩展一下返回参数,这个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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    再业务中,从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认证失败'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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 "", 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.
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

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

  • 相关阅读:
    磁钢的居里温度和工作温度
    【逆向专题】【危!!!刑】(一)使用c#+Win32Api实现进程注入到wechat
    【kerberos】win环境下kerberos认证工具类
    Elasticsearch 8.9 Master节点处理请求源码
    html + css + js 基础
    kafka生产者
    MQTT介绍和使用
    React之组件实例的三大属性之props
    【C语言】嵌套结构体初始化 - 一个有趣的结论
    【黑马程序员】Python文件、异常、模块、包
  • 原文地址:https://blog.csdn.net/warrah/article/details/126508244