美文网首页Nginx高端成长之路程序员Openresty
一个OpenResty里OAuth 2认证的轮子(上)

一个OpenResty里OAuth 2认证的轮子(上)

作者: 槑菜干超人 | 来源:发表于2017-06-30 11:18 被阅读534次

    写在前面:本文只水水地讨论如何去登陆一个OAuth平台并获取用户信息,并没有涉及如何实现一个OAuth平台


    更新:
    本系列中篇
    本系列下篇
    本系列补遗


    OpenResty一直是我很看好的后端技术栈:在Nginx的高性能Web服务器基础上,用Lua这个精巧的语言来扩展业务逻辑的编写能力;工具的封装也非常干净好用,看上去挺符合我对“小而美”的理解。

    之前用过OpenResty写了一些不太复杂的东西,主要还是偏向业务相关为主。但长久以来我一直想用OpenResty做些更偏基础设施、或者更基础协议方面的东西。一年多前在网上找了一阵子,发现好像没有一个相对精简而独立的OAuth 2库(嗯是的其实是我眼瞎,这个库在两年前就挂在Github上了),便萌生了自己做一个的想法——显然已经被磨磨叽叽地拖延了一年多——一半是因为自己的拖延症一半是因为自己的水平菜。

    最近终于不能忍受如此没有效率的自己,擦亮屏幕读文档撸起袖管写代码,还真搞得差不多了。多说无益,放码过来吧!

    首先,我们先建一个文件夹来放项目的所有东西:

    $ mkdir -p demo/resty/{conf,logs}
    $ cd demo
    

    要做一个良心demo,最重要的是大家都跑得起来。所以我这里用Docker来隔离平台上的区别。为了节省大家宝贵的带宽,我贴一个简单的Dockerfile,这个是基于OpenResty官方Alpine版本(原维护人Evan Wies evan@neomantra.net),又扩展了一些我们会需要用到的东西,去掉了几个我们用不到的模块的编译来节省时间。但求能用,不求Dockerfile编写的最佳实践,把下面东西扔进项目根目录的Dockerfile里就好:

    # Dockerfile
    FROM alpine:latest
    
    # Docker Build Arguments
    ARG RESTY_VERSION="1.11.2.3"
    ARG RESTY_OPENSSL_VERSION="1.0.2k"
    ARG RESTY_PCRE_VERSION="8.39"
    ARG RESTY_J="1"
    ARG RESTY_CONFIG_OPTIONS="\
        --with-http_addition_module \
        --with-pcre-jit \
        "
    
    # These are not intended to be user-specified
    ARG _RESTY_CONFIG_DEPS="--with-openssl=/tmp/openssl-${RESTY_OPENSSL_VERSION} --with-pcre=/tmp/pcre-${RESTY_PCRE_VERSION}"
    
    
    # 1) Install apk dependencies
    # 2) Download and untar OpenSSL, PCRE, and OpenResty
    # 3) Build OpenResty
    # 4) Cleanup
    
    RUN \
        apk add --no-cache --virtual .build-deps \
            build-base \
            gd-dev \
            geoip-dev \
            libxslt-dev \
            linux-headers \
            make \
            perl-dev \
            readline-dev \
            zlib-dev \
        && apk add --no-cache \
            gd \
            geoip \
            libgcc \
            libxslt \
            zlib \
            curl \
            perl \
        && cd /tmp \
        && curl -fSL https://www.openssl.org/source/openssl-${RESTY_OPENSSL_VERSION}.tar.gz -o openssl-${RESTY_OPENSSL_VERSION}.tar.gz \
        && tar xzf openssl-${RESTY_OPENSSL_VERSION}.tar.gz \
        && curl -fSL https://ftp.pcre.org/pub/pcre/pcre-${RESTY_PCRE_VERSION}.tar.gz -o pcre-${RESTY_PCRE_VERSION}.tar.gz \
        && tar xzf pcre-${RESTY_PCRE_VERSION}.tar.gz \
        && curl -fSL https://openresty.org/download/openresty-${RESTY_VERSION}.tar.gz -o openresty-${RESTY_VERSION}.tar.gz \
        && tar xzf openresty-${RESTY_VERSION}.tar.gz \
        && cd /tmp/openresty-${RESTY_VERSION} \
        && ./configure -j${RESTY_J} ${_RESTY_CONFIG_DEPS} ${RESTY_CONFIG_OPTIONS} \
        && make -j${RESTY_J} \
        && make -j${RESTY_J} install \
        && cd /tmp \
        && rm -rf \
            openssl-${RESTY_OPENSSL_VERSION} \
            openssl-${RESTY_OPENSSL_VERSION}.tar.gz \
            openresty-${RESTY_VERSION}.tar.gz openresty-${RESTY_VERSION} \
            pcre-${RESTY_PCRE_VERSION}.tar.gz pcre-${RESTY_PCRE_VERSION} \
        && apk del .build-deps \
        && ln -sf /dev/stdout /usr/local/openresty/nginx/logs/access.log \
        && ln -sf /dev/stderr /usr/local/openresty/nginx/logs/error.log
    
    # Add additional binaries into PATH for convenience
    ENV PATH=$PATH:/usr/local/openresty/luajit/bin/:/usr/local/openresty/nginx/sbin/:/usr/local/openresty/bin/
    
    RUN opm get bungle/lua-resty-session && opm get pintsized/lua-resty-http
    

    如果要图方便,还可以再搞一个docker-compose的配置,不然直接用Docker的原生命令也可以(command里跑的东西后面会提到):

    # docker-compose.yml
    web:
      build: .
      ports:
        - "80:80"
      volumes:
        - .:/var/www/demo
      command: "sh -c 'openresty -p /var/www/demo/resty && tail -f /var/www/demo/resty/logs/error.log'"
    

    接下来就到了愉快的写(tie)代(pei)码(zhi)时间!把下面的东西扔进 resty/conf/nginx.conf 文件里:

    worker_processes  1;
    error_log logs/error.log debug;
    events { worker_connections 1024; }
    
    http {
      server {
        listen 80;
    
        location / {
          content_by_lua_block {
            ngx.say('hello world')
          }
        }
      }
    }
    

    现在我们项目文件夹里的东西应该有这些:

    $ tree
    .
    ├── Dockerfile
    ├── docker-compose.yml
    └── resty
        ├── conf
        │   └── nginx.conf
        └── logs
    
    3 directories, 3 files
    

    激动人心的时刻到了!轻敲 docker-compose up,整个屏幕就会布满酷炫的容器构建信息。构建完之后,简单测试一下:

    $ curl -v localhost
    * Rebuilt URL to: localhost/
    *   Trying ::1...
    * connect to ::1 port 80 failed: Connection refused
    *   Trying 127.0.0.1...
    * Connected to localhost (127.0.0.1) port 80 (#0)
    > GET / HTTP/1.1
    > Host: localhost
    > User-Agent: curl/7.43.0
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Server: openresty/1.11.2.3
    < Date: Fri, 30 Jun 2017 02:51:34 GMT
    < Content-Type: text/plain
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    <
    hello world
    * Connection #0 to host localhost left intact
    

    俗话说,良好的Hello World是成功的一半,现在Demo里Nginx和OpenResty相关的部分都很直接,大家应该都能读懂,唯一稍微解释一下的就是compose配置里的那句 openresty -p /var/www/demo:OpenResty有一个命令 openresty,和Nginx的 nginx 命令几乎一样,所以说 -p 所做的就是指定启动路径啦:

    $ openresty -h
    nginx version: openresty/1.11.2.3
    Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
    
    Options:
      -?,-h         : this help
      -v            : show version and exit
      -V            : show version and configure options then exit
      -t            : test configuration and exit
      -T            : test configuration, dump it and exit
      -q            : suppress non-error messages during configuration testing
      -s signal     : send signal to a master process: stop, quit, reopen, reload
      -p prefix     : set prefix path (default: /usr/local/openresty/nginx/)
      -c filename   : set configuration file (default: conf/nginx.conf)
      -g directives : set global directives out of configuration file
    

    现在趁自己还在一种兴奋和喜悦之中——赶紧把一些无聊的事情做了:注册一个OAuth App。我在这个项目中会用世界最大的码农交友社区Github的登录来做例子,大家可以翻一下它的新App注册流程,非常简单直观,注册完就会得到对应的Client ID和Client Secret(马赛克部分):

    我的测试App

    截图最下面的那个URL,是OAuth验证的回调,到时候我们还会用得上。

    上部就先写到这里,主要搭建了一个能在Docker里跑起来的OpenResty实例,注册了一个Github的App,剩下还有一个准备工作,就是需要阅读并理解OAuth 2的登录流程,这块大家可以参考阮一峰的一篇旧博客——我知道他在微博上被喷得很厉害,但是这篇博客作为OAuth 2的流程入门还是不错的。

    相关文章

      网友评论

        本文标题:一个OpenResty里OAuth 2认证的轮子(上)

        本文链接:https://www.haomeiwen.com/subject/zsjbcxtx.html