寫在前面:本文只水水地討論如何去登陸一個(gè)OAuth平臺(tái)并獲取用戶信息亩鬼,并沒有涉及如何實(shí)現(xiàn)一個(gè)OAuth平臺(tái)
OpenResty一直是我很看好的后端技術(shù)棧:在Nginx的高性能Web服務(wù)器基礎(chǔ)上志电,用Lua這個(gè)精巧的語言來擴(kuò)展業(yè)務(wù)邏輯的編寫能力;工具的封裝也非常干凈好用,看上去挺符合我對(duì)“小而美”的理解。
之前用過OpenResty寫了一些不太復(fù)雜的東西,主要還是偏向業(yè)務(wù)相關(guān)為主顷歌。但長(zhǎng)久以來我一直想用OpenResty做些更偏基礎(chǔ)設(shè)施、或者更基礎(chǔ)協(xié)議方面的東西阶淘。一年多前在網(wǎng)上找了一陣子衙吩,發(fā)現(xiàn)好像沒有一個(gè)相對(duì)精簡(jiǎn)而獨(dú)立的OAuth 2庫(嗯是的其實(shí)是我眼瞎互妓,這個(gè)庫在兩年前就掛在Github上了)溪窒,便萌生了自己做一個(gè)的想法——顯然已經(jīng)被磨磨嘰嘰地拖延了一年多——一半是因?yàn)樽约旱耐涎影Y一半是因?yàn)樽约旱乃讲恕?/p>
最近終于不能忍受如此沒有效率的自己,擦亮屏幕讀文檔擼起袖管寫代碼冯勉,還真搞得差不多了澈蚌。多說無益,放碼過來吧灼狰!
首先宛瞄,我們先建一個(gè)文件夾來放項(xiàng)目的所有東西:
$ mkdir -p demo/resty/{conf,logs}
$ cd demo
要做一個(gè)良心demo,最重要的是大家都跑得起來交胚。所以我這里用Docker來隔離平臺(tái)上的區(qū)別份汗。為了節(jié)省大家寶貴的帶寬,我貼一個(gè)簡(jiǎn)單的Dockerfile蝴簇,這個(gè)是基于OpenResty官方Alpine版本(原維護(hù)人Evan Wies evan@neomantra.net)杯活,又?jǐn)U展了一些我們會(huì)需要用到的東西,去掉了幾個(gè)我們用不到的模塊的編譯來節(jié)省時(shí)間熬词。但求能用旁钧,不求Dockerfile編寫的最佳實(shí)踐吸重,把下面東西扔進(jìn)項(xiàng)目根目錄的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
如果要圖方便,還可以再搞一個(gè)docker-compose的配置歪今,不然直接用Docker的原生命令也可以(command里跑的東西后面會(huì)提到):
# 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)時(shí)間嚎幸!把下面的東西扔進(jìn) 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')
}
}
}
}
現(xiàn)在我們項(xiàng)目文件夾里的東西應(yīng)該有這些:
$ tree
.
├── Dockerfile
├── docker-compose.yml
└── resty
├── conf
│ └── nginx.conf
└── logs
3 directories, 3 files
激動(dòng)人心的時(shí)刻到了!輕敲 docker-compose up
寄猩,整個(gè)屏幕就會(huì)布滿酷炫的容器構(gòu)建信息嫉晶。構(gòu)建完之后,簡(jiǎn)單測(cè)試一下:
$ 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是成功的一半车遂,現(xiàn)在Demo里Nginx和OpenResty相關(guān)的部分都很直接,大家應(yīng)該都能讀懂斯辰,唯一稍微解釋一下的就是compose配置里的那句 openresty -p /var/www/demo
:OpenResty有一個(gè)命令 openresty
舶担,和Nginx的 nginx
命令幾乎一樣,所以說 -p
所做的就是指定啟動(dòng)路徑啦:
$ 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
現(xiàn)在趁自己還在一種興奮和喜悅之中——趕緊把一些無聊的事情做了:注冊(cè)一個(gè)OAuth App彬呻。我在這個(gè)項(xiàng)目中會(huì)用世界最大的碼農(nóng)交友社區(qū)Github的登錄來做例子衣陶,大家可以翻一下它的新App注冊(cè)流程,非常簡(jiǎn)單直觀闸氮,注冊(cè)完就會(huì)得到對(duì)應(yīng)的Client ID和Client Secret(馬賽克部分):
截圖最下面的那個(gè)URL剪况,是OAuth驗(yàn)證的回調(diào),到時(shí)候我們還會(huì)用得上蒲跨。
上部就先寫到這里译断,主要搭建了一個(gè)能在Docker里跑起來的OpenResty實(shí)例,注冊(cè)了一個(gè)Github的App或悲,剩下還有一個(gè)準(zhǔn)備工作孙咪,就是需要閱讀并理解OAuth 2的登錄流程,這塊大家可以參考阮一峰的一篇舊博客——我知道他在微博上被噴得很厲害巡语,但是這篇博客作為OAuth 2的流程入門還是不錯(cuò)的翎蹈。