GitLab: 使用用户名/密码创建Access Token的暂定方法

在这里插入图片描述

GitLab升级到后续的版本之后,由于Session API已经不再支持,通过用户名/密码方式获取Access Token的方式需要换一种方式,这篇文章介绍一下一种通过使用cookie获取的方式。

原有方式:v3的Session API

早期版本,比如Gitlab 8,可以通过如下方式轻松获得Private Token

[root@platform tmp]# curl http://192.168.163.118:32001/api/v3/session --data 'login=root&password=12345678' 2>/dev/null |jq . |grep token 
  "private_token": "9-9rh18mQz4h3eDMQf5M"
[root@platform tmp]#

详细可参看:https://blog.csdn.net/liumiaocn/article/details/81291556

不可使用原因:随着Access Token功能的全面升级,对于token也能做到多个token以及过期日期的更细粒度的控制,session api也完成了其作用,已经不再支持。

暂定方法

思路:使用cookie,模拟页面操作的方式传入信息,然后从返回的html页面从提取相应的结果内容。

环境准备

docker-compose文件

liumiaocn:gitlab liumiao$ cat docker-compose.yml 
version: '2'    
services:
  # Version Control service: Gitlab
  gitlab:
    image: gitlab/gitlab-ce:12.10.5-ce.0
    ports:
      - "32001:80"
    volumes:
      - ./log/:/var/log/gitlab
      - ./data/:/var/opt/gitlab
      - ./conf/:/etc/gitlab
    restart: "no"
liumiaocn:gitlab liumiao$ 

事前准备

创建如下目录:

liumiaocn:gitlab liumiao$ ls
docker-compose.yml
liumiaocn:gitlab liumiao$ mkdir -p log data conf
liumiaocn:gitlab liumiao$ ls
conf			data			docker-compose.yml	log
liumiaocn:gitlab liumiao$ 

启动

启动命令:docker-compose up -d

登录URL

  • http://localhost:32001

在这里插入图片描述
注:此处设定root用户密码为liumiaocn,后续将使用root/liumiaocn创建和获取Access Token。

步骤1: 获取认证token

使用如下示例命令获取认证token信息,此信息将在步骤2模拟页面登录时使用

liumiaocn:api liumiao$ curl -c cookie.txt -i "http://localhost:32001/users/sign_in" -s >token.txt
liumiaocn:api liumiao$

生成的cookie详细

liumiaocn:api liumiao$ cat cookie.txt 
# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

#HttpOnly_localhost	FALSE	/	FALSE	1595212892	_gitlab_session	58ca351d122f3ca23c0eb2a01461a3b2
#HttpOnly_localhost	FALSE	/	FALSE	2226357692	experimentation_subject_id	IjcwNWRmZWM2LTcyZWItNGFjNy1iNjJhLTkzMDlkYjg3N2Y1NSI%3D--91dcd3115eb28a5d079a440e429b658b46acae5f
liumiaocn:api liumiao$ 

token.txt详细内容中包含csrf内容

liumiaocn:api liumiao$ cat token.txt 
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 20 Jul 2020 00:41:32 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: max-age=0, private, must-revalidate
Etag: W/"1756ae89b2b0f51b4c950a1f4ac0add7"
Referrer-Policy: strict-origin-when-cross-origin
Set-Cookie: experimentation_subject_id=IjcwNWRmZWM2LTcyZWItNGFjNy1iNjJhLTkzMDlkYjg3N2Y1NSI%3D--91dcd3115eb28a5d079a440e429b658b46acae5f; path=/; expires=Fri, 20 Jul 2040 00:41:32 -0000; HttpOnly
Set-Cookie: _gitlab_session=58ca351d122f3ca23c0eb2a01461a3b2; path=/; expires=Mon, 20 Jul 2020 02:41:32 -0000; HttpOnly
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-Request-Id: MLxE09OKZz5
X-Runtime: 0.049925
X-Ua-Compatible: IE=edge
X-Xss-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000
Referrer-Policy: strict-origin-when-cross-origin

<!DOCTYPE html>
<html class="devise-layout-html">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
...省略

<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="1Q8FE1gGh9RnG+YE3FWXKqN/Twh6AQJ4roEVfqzmz5MYBNXOTMqpwtAs0W10V4NxfmFIME+RCUNpQjfhssiSQQ==" />

<meta content="origin-when-cross-origin" name="referrer">
<meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport">
...省略
<div class="login-body">
<form class="new_user gl-show-field-errors" id="new_user" aria-live="assertive" action="/users/sign_in" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><input type="hidden" name="authenticity_token" value="wN23/hzgdq3+XfeZAq5xKYOZ/6j1pDt0Pz5hSGkzILoN1mcjCCxYu0lqwPCqrGVyXof4kMA0ME/4/UPXdx19aA==" /><div class="form-group">
<label for="user_login" class="label-bold">Username or email</label>
...省略
</body>
</html>
liumiaocn:api liumiao$ 

从上述返回中提取token的信息“wN23/hzgdq3+XfeZAq5xKYOZ/6j1pDt0Pz5hSGkzILoN1mcjCCxYu0lqwPCqrGVyXof4kMA0ME/4/UPXdx19aA==”

步骤2: 模拟页面登录

使用用户名、密码以及获取的认证token信息以及cookie文件,通过users/sign_in传入,模拟页面登录方式

liumiaocn:api liumiao$ curl -b cookie.txt -c cookie.txt -i "http://localhost:32001/users/sign_in" \
> --data "user[login]=root&user[password]=liumiaocn" \
> --data-urlencode "authenticity_token=wN23/hzgdq3+XfeZAq5xKYOZ/6j1pDt0Pz5hSGkzILoN1mcjCCxYu0lqwPCqrGVyXof4kMA0ME/4/UPXdx19aA=="
HTTP/1.1 302 Found
Server: nginx
Date: Mon, 20 Jul 2020 01:37:40 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 89
Connection: keep-alive
Cache-Control: max-age=0, private, must-revalidate, no-store
Location: http://localhost:32001/
Pragma: no-cache
Referrer-Policy: strict-origin-when-cross-origin
Set-Cookie: _gitlab_session=2bd98a7c373ebabdd84616e83bfe592e; path=/; HttpOnly
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-Request-Id: P6GPvq6Czg7
X-Runtime: 0.729474
X-Ua-Compatible: IE=edge
X-Xss-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000
Referrer-Policy: strict-origin-when-cross-origin

<html><body>You are being <a href="http://localhost:32001/">redirected</a>.</body></html>liumiaocn:api liumiao$ 
liumiaocn:api liumiao$ 

步骤3: 模拟移动至profile/personal_access_tokens

使用cookie文件作为输入,模拟移动至profile/personal_access_tokens页面

liumiaocn:api liumiao$ curl -H 'user-agent: curl' -b cookie.txt -i "http://localhost:32001/profile/personal_access_tokens" -s >token2.txt
liumiaocn:api liumiao$

确认token信息:

liumiaocn:api liumiao$ grep authenticity_token token2.txt 
<meta name="csrf-param" content="authenticity_token" />
<form class="js-requires-input" id="new_personal_access_token" action="/profile/personal_access_tokens" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><input type="hidden" name="authenticity_token" value="vV3nI5JjJeMPO+RlCSS6SmIs1P1xzWRsfy4X1r/sxuqFhpaXCHIIRUuZ6ga2VT1y8gbSpdHd6bU7Mh4p9mP/Ng==" />
liumiaocn:api liumiao$ 

确认cookie信息

liumiaocn:api liumiao$ cat cookie.txt 
# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

#HttpOnly_localhost	FALSE	/	FALSE	2226357692	experimentation_subject_id	IjcwNWRmZWM2LTcyZWItNGFjNy1iNjJhLTkzMDlkYjg3N2Y1NSI%3D--91dcd3115eb28a5d079a440e429b658b46acae5f
#HttpOnly_localhost	FALSE	/	FALSE	0	_gitlab_session	2bd98a7c373ebabdd84616e83bfe592e
liumiaocn:api liumiao$ 

步骤4:创建token

创建名为ap-token-test的token,类别为api

liumiaocn:api liumiao$ curl -L -b cookie.txt "http://localhost:32001/profile/personal_access_tokens" \
> --data-urlencode "authenticity_token=vV3nI5JjJeMPO+RlCSS6SmIs1P1xzWRsfy4X1r/sxuqFhpaXCHIIRUuZ6ga2VT1y8gbSpdHd6bU7Mh4p9mP/Ng==" \
> --data 'personal_access_token[name]=ap-token-test&personal_access_token[expires_at]=&personal_access_token[scopes][]=api' >token3.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   349  100   119  100   230   1487   2875 --:--:-- --:--:-- --:--:--  4362
100 35977    0 35977    0     0   145k      0 --:--:-- --:--:-- --:--:--  145k
liumiaocn:api liumiao$

注:本来是想写成api-token-test的,写错了,不过不影响结果

步骤5:确认token信息

token仅仅在首次创建时出现,我们可以很容易地从token3.txt中获取此token信息

liumiaocn:api liumiao$ grep created-personal-access-token token3.txt 
<div class="created-personal-access-token-container">
<input type="text" name="created-personal-access-token" id="created-personal-access-token" value="JmHBHzaRxUQoyWdPdES_" readonly="readonly" class="qa-created-personal-access-token form-control js-select-on-focus" aria-describedby="created-token-help-block" />
liumiaocn:api liumiao$ 

在这里插入图片描述

步骤6:验证token

通过一个api的使用来验证此token是好用的,执行日志示例如下所示:

liumiaocn:api liumiao$ gitlab_url="localhost:32001"
liumiaocn:api liumiao$ access_token="JmHBHzaRxUQoyWdPdES_"
liumiaocn:api liumiao$ curl -H "PRIVATE-TOKEN: ${access_token}" http://${gitlab_url}/api/v4/user/keys
[]liumiaocn:api liumiao$ 

总结

虽然使用用户名/密码去直接获取access token总会有很多被诟病的地方,但是如果不希望登录gitlab进行操作的话,这也是一种纠结的解决方法。

猜你喜欢

转载自blog.csdn.net/liumiaocn/article/details/107455737