• 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

  • 相关阅读:
    【微服务~Nacos】Nacos服务提供者和服务消费者
    打造千万级流量秒杀第二十二课 本地缓存实战:如何使用内存缓存提升数据命中率?
    【Linux】grep显示行号的时候,冒号和减号的区别
    线性DP问题
    LQ0153 字串排序【排序】
    大模型:如何利用旧的tokenizer训练出一个新的来?
    Hbuilder打包安卓H5-APP,APP与程序分离,更新无需重新打包
    Windows和Linux的环境变量
    tomcat的优化
    根据语义切分视频
  • 原文地址:https://blog.csdn.net/warrah/article/details/126508244