简体   繁体   English

通过将 POST 请求中的 HTML 表单发送到私有 API 来获取 JWT

[英]Get JWT by sending HTML form in POST request to private API

I have created a very simple html page with 2 inputs and a button (username, password and log in/submit).我创建了一个非常简单的 html 页面,其中包含 2 个输入和一个按钮(用户名、密码和登录/提交)。 When I press submit, the username and password is converted into JSON, and sent as the body of a POST request to a private API which I have no control over.当我按下提交时,用户名和密码被转换为 JSON,并作为 POST 请求的正文发送到我无法控制的私有 API。 The API should then respond with another JSON containing a JWT access token.然后,API 应使用另一个包含 JWT 访问令牌的 JSON 进行响应。 I then need to put this token into the request header of a GET request (Bearer token), but I haven't gotten this far yet, hence why I'm here.然后我需要将此令牌放入 GET 请求(不记名令牌)的请求标头中,但我还没有做到这一点,因此我在这里。

I have tested the API with Postman, and it is working perfectly as expected.我已经用 Postman 测试了 API,它按预期完美运行。 I am now trying to do what Postman does, only in my own small web application.我现在正在尝试做 Postman 所做的事情,只是在我自己的小型 Web 应用程序中。

The JSON I need to send is like this:我需要发送的 JSON 是这样的:

{"username": "someUsername", "password": "somePassword"}

And the response is like this:响应是这样的:

{"access_token": "A very long random string"}

Here is my code so far:到目前为止,这是我的代码:

HTML: HTML:

<link href="/resources/css/bootstrap.min.css" rel="stylesheet">
<script src="apirequest.js"></script>
<div class="container">
    <form class="form-signin">
        <h2 class="form-heading">Send POST request</h2>
        <div class="form-group">
            <input type="text" id="username" class="form-control" placeholder="Username" autofocus /> 
            <input type="password" id="password" class="form-control" placeholder="Password" />
            <button class="btn btn-lg btn-primary btn-block" type="submit" onclick="getToken()">Log in</button>
        </div>
    </form>
</div>

apirequest.js this URL is not the real one apirequest.js 这个网址不是真的

alert("script loaded");
var token_;

function getToken() {

    alert("button pressed");

    var request = new XMLHttpRequest();

    var key;
    var username_ = document.getElementById("username").val();
    var password_ = document.getElementById("password").val();

    request.open("POST", "https://api.dummyurl.test", true);
    request.setRequestHeader("Content-type", "application/json");
    request.send(JSON.stringify({
        username: username_,
        password: password_
    }));
    request.onreadystatechange = function() {
        if (request.readyState == 4 && request.status == 200) {
            var response = request.responseText;
            var obj = JSON.parse(response);
            key = obj.access_token; // store the value of the accesstoken
            token_ = key; // store token in global variable "token_"
            alert(token_); //test if token is stored
        }
    }
}

I have put some alerts in there just to test things;我在那里放了一些警报只是为了测试; I get "script loaded" and "button pressed", but not the alert with the token.我收到“脚本加载”和“按钮按下”,但没有收到带有令牌的警报。

I have also tried with AJAX/jQuery to no avail, also no alert pop up:我也试过 AJAX/jQuery 无济于事,也没有弹出警报:

<script type="text/javascript">
        $(document).ready(function() {
            $(".btn").click(function() {
                alert("Script loaded");
                const Data = {
                    "username" : document.getElementById("username").val(),
                    "password" : document.getElementById("password").val()
                }

                $.ajax({
                    url : "https://api.dummyurl.test",
                    type : "POST",
                    data : Data,
                    contentType : "application/json; charset=utf-8",
                    dataType : "json",
                    success : function(result) {
                        alert(result)
                        console.log(result)
                    },
                    error : function(error) {
                        console.log(error)
                    }
                })
            })
        })
    </script>

I load the page and get "script loaded", then I enter a valid username and password, then I get "button pressed".我加载页面并“加载脚本”,然后输入有效的用户名和密码,然后“按下按钮”。 The page just refreshes and I get "script loaded" again with the last username already typed in. None of the questions I've read have had an answer that works for me.页面刚刚刷新,我再次使用已输入的最后一个用户名“加载脚本”。我读过的所有问题都没有对我有用的答案。 Do you see any problems with my code?你看到我的代码有什么问题吗? Also, as a last note;另外,作为最后一点; I'd like to use the first script example as that one is much easier to understand and work with for me.我想使用第一个脚本示例,因为它对我来说更容易理解和使用。

Update更新

So, it's kind of working.所以,它有点工作。 I didn't know Postman generated code I could copy.我不知道 Postman 生成的代码我可以复制。 As mentioned, I have tested the API with Postman and it works.如前所述,我已经用 Postman 测试了 API 并且它有效。 Here's what the script looks like now:下面是脚本现在的样子:

$(document).ready(function() {
    var settings = {
            "async" : true,
            "crossDomain" : true,
            "url" : "https://api.dummyurl.test",
            "method" : "POST",
            "headers" : {
                "Content-Type" : "application/json",
                "cache-control" : "no-cache"
                    },
                    "processData" : false,
                    "data" : "{  \r\n\"Username\":\"someUsername\",\r\n\"Password\":\"somePassword\"\r\n}"
                    }
    $.ajax(settings).done(function(response) {
        console.log(response);
        });
    })

I actually got the access token from this.我实际上从中获得了访问令牌。 The problem now is that username and password is hardcoded (not from html input) and that the script runs as soon as the page is loaded.现在的问题是用户名和密码是硬编码的(不是来自 html 输入)并且脚本在页面加载后立即运行。 Any ideas how I can make the script run only after I press the button?有什么想法可以让我在按下按钮后才运行脚本吗? And how I can replace the hardcoded username and password with the values from the input fields?以及如何用输入字段中的值替换硬编码的用户名和密码? Postman generated code with so many \\ and ", can I still use variables and not strings inside that line of code?邮递员生成的代码有这么多 \\ 和 ",我还能在那行代码中使用变量而不是字符串吗?

I just tried reformatting the data to {"Username":"someUsername","Password":"somePassword"} and it wouldn't work that way, so I guess the \\r\\n is necessary?我只是尝试将数据重新格式化为{"Username":"someUsername","Password":"somePassword"}并且它不会那样工作,所以我猜 \\r\\n 是必要的?

Your forgot the method on your form element, While serialize method will get form values, try to set your form like this:您忘记了表单元素上的方法,虽然序列化方法将获取表单值,但请尝试像这样设置表单:

   <form class="form-signin" method="post">
        <h2 class="form-heading">Send POST request</h2>
        <div class="form-group">
            <input type="text" id="username" class="form-control" placeholder="Username" autofocus /> 
            <input type="password" id="password" class="form-control" placeholder="Password" />
            <button class="btn btn-lg btn-primary btn-block" type="submit" onclick="return getToken(this.form)">Log in</button>
        </div>
    </form>


   <script type="text/javascript">
      $(document).ready(function() {
        function getToken(form){
          var formData = $(form).serialize();
          $.post("https://api.dummyurl.test", formData).done(function(result){
            alert(result);
            console.log(result)
          })
          return true;
        }

      })
   </script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM