# cngx用户认证代码理解

着重看`common_util.readRequestArgs`方法

然后先`ngx.req.read_body()`用于后面的读body

`ngx.req.get_uri_args()`用于读get参数，以key\value的形式，即table类型

urlArgs 添加字段 `__startDealTime` 当前处理时间

`local reqHeaders = ngx.req.get_headers(0) or {}` 把headers中的key\value放到reqHeaders 中

`common_util.get_data()` 中内嵌 `ngx.req.get_body_data()` 方法，获取的是bodyStr

用`ngx.var.uri`获取path

`if not flag ` 这个逻辑没看懂，之后再细看下

`reqBody = cjson_safe.decode(reqBodyStr)` 继续body字符串，这种解析安卓端会nil，如果nil，用`reqBody = ngx.decode_args(reqBodyStr) or {}`进行解析
如果解析失败，打印错误日志，拒绝请求

再拿一下urlPath，和`/appc/xxxx`进行匹配，这个是socket请求，如果匹配到，就拿`appc_util.transferCore`方法从`api_content`、`reqBody`、`urlArgs`中筛选各个参数，放到reqBody中

然后进入middlewareCheck.check方法

## validateToken

`path = string.gsub( path, "/v4/", "/")`把/v4/换成/

如果path来自于`/ccb/ccbCallback` 且args或者body中有callback参数，置为nil，并且通过该层校验

如果headers中参数from字段 == "cc"，通过该层校验

然后获取userID、version、platform

如果用户userID 属于内部人员，且环境也能对应，通过该层校验

对userID进行字符校验（字符串长度、和字母限制），不符合规则的，验证失败5003
这一层校验，userID = "" 是允许通过的

匹配path，`/internal/`和`/appc/`通过校验

剩下的，就行token验证。

### tokenCheckConfig.validateNewToken

这里是根据url、version、userid、new-token 进行过滤，返回 {status}

具体细则为

userid不存在、appversion<4.9.5、path=/user/sendValidateTokenForRegist且不存在new-token、path in tokenCheckConfig.ignoreNewTokenUrls 时
返回 {status = "1"} ,nil 验证通过

new-token 不存在时，如果path = ""/appInfo/getStartImg" , status=1, 否则 status="3"
返回 {status = "3"} ,nil 验证通过

用new-token 查 middleware_util.middlewareTokenCheck
如果返回nil，可能有两种情况：1、请求status != 200 ，比如说超时，或者程序错误，这种情况肯定是要允许通过拦截的；2、代码错误，走到的第二个nil，会有日志抛出，并且也要通过校验。
正常情况下，不会返回nil，会返回一个json，里面包含status，user_id，
status如果 == "1"，那么即将返回{status = "1"} ,nil
status如果 ~= "1"，那么即将返回{status = "3"} ,nil
如果userID ~= responseUserId 那么返回{status = "3"} ,nil

### status

如果data.status == "3"，验证失败5100

### 进入第一层加密

如果path 不在 tokenCheckConfig.ignoreTokenUrls 中，进入第一层加密

通过tokenCheckConfig.buildParamStr方法，把body和args中所有的key\value，按照一定的顺序排序，然后转string，然后拼接，最后拼一个url("/v4/"——>"")
这样拼的字符串叫paraStr

然后获取reqHeaders中的token字段

**tokenCheckConfig.valideAESToken**

该方法，根据`paraStr`、`version`、`platform`、`data`生成`desStr`
具体生成规则，请详细看配置文件
返回`desStr` == `token` 

如果返回`false`，5100

### 第二层加密

针对于`tokenCheckConfig.coreFuncs[path]` 会执行第二层加密

## checkAuthorization

