如何使用 Python 和/或 Javascript 自动验证 ngrok 密码?

How to authenticate ngrok password automatically using Python and or Javascript?

我正在使用 ngrok 在 raspberry pi 上公开我的本地主机,并且 ngrok 受密码保护。我在网络外的另一台计算机上使用 Django 来访问此 raspberry pi 上的网页(简单服务器)。我不想手动输入 ngrok 的用户名和密码。

如何自动填写 ngrok user/password,它是 chrome 中要求用户和密码的弹出窗口?

我尝试过的: 我首先尝试在我的模板中使用 JS,仅使用获取请求: https://user:password@myngrokdomain.ngrok.io 但 chrome 在控制台中抛出一个错误,说我不能像这样以纯文本形式传递凭据,这是理所当然的......

然后我尝试使用 python 请求:

    UN= "myuser"
    PWD = "mypassword"
    loginURL = "https://myngrokdomain.ngrok.io"
    client = requests.session()
    login_data = dict(username=UN, password=PWD,)
    r = client.post(loginURL, data=login_data)

这返回了 401 拒绝访问

r.headers + r.reasonreturns: 401 Unauthorized Unauthorized {'Content-Length': '16', 'Content-Type': 'text/plain', 'Www-Authenticate': 'Basic realm="ngrok"', 'Date': 'Tue, 16 Mar 2021 15:22:15 GMT'}

首先尝试在登录页面上执行获取操作。也许它正在设置一些它希望出现在 post 上的 cookie:

    UN= "myuser"
    PWD = "mypassword"
    loginURL = "https://myngrokdomain.ngrok.io"
    client = requests.session()
    login_data = dict(username=UN, password=PWD,)
    client.get(loginURL )
    r = client.post(loginURL, data=login_data)

ngrok 使用的身份验证方法称为 HTTP Basic Auth。要将它与请求库一起使用,您需要在 auth 参数中将登录名和密码作为元组传递:

r = client.post(loginURL, auth=(UN, PWD))

文档:Basic Authentication — Requests

您需要区分您是从浏览器还是服务器应用程序发出请求。

浏览器

如果您是通过浏览器执行此操作,则会遇到 CORS 问题,而 ngrok 在提供 --auth 时不支持该问题。来自 docs:

you cannot use ngrok's -auth option. ngrok's http tunnels allow you to specify basic authentication credentials to protect your tunnels. However, ngrok enforces this policy on all requests, including the preflight OPTIONS requests that are required by the CORS spec. In this case, your application must implement its own basic authentication

在这种情况下,您唯一的选择是在您的应用程序中实施身份验证,而不是使用 ngrok 的 --auth

服务器

如果您从服务器应用程序发送请求,则不会遇到任何 CORS 问题,但您需要正确提供基本身份验证凭据。

假设您的应用程序通过 http://myapp.ngrok.io 处的 ngrok 公开,通过 --auth user:pass.

保护

在普通的 Node.js 你会做这样的事情:

const http = require('http')

http.get('http://myapp.ngrok.io', { auth: 'user:pass' }, res => {
  const chunks = []

  res.on('data', chunk => {
    chunks.push(chunk)
  })

  res.on('end', () => {
    console.log(Buffer.concat(chunks).toString('utf-8'))
  })
})

请注意,要访问 https url,您将使用 Node 的 https 模块而不是 http,或者使用更高级别的库来为您处理,例如 node-fetch.

在 Python 中,您可以做类似的事情, 可能会让您走上正确的道路。