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

时间:2019-04-19 17:38:39

标签: javascript html json post

我创建了一个非常简单的html页面,其中包含2个输入和一个按钮(用户名,密码和登录/提交)。当我按Submit时,用户名和密码将转换为JSON,并作为POST请求的正文发送到我无法控制的私有API。然后,API应使用另一个包含JWT访问令牌的JSON进行响应。然后,我需要将此令牌放入GET请求的请求标头中(承载令牌),但是我还没有走到这一步,所以我为什么在这里。

我已经用Postman测试了API,并且可以按预期正常运行。我现在仅在自己的小型Web应用程序中尝试做Postman所做的事情。

我需要发送的JSON是这样的:

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

响应如下:

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

到目前为止,这是我的代码:

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,此网址不是真正的网址

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
        }
    }
}

我在其中放置了一些警报,目的只是为了测试事情;我收到“脚本已加载”和“按钮按下”的消息,但没有带有令牌的警报。

我也尝试过使用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>

我加载页面并获得“脚本加载”,然后输入有效的用户名和密码,然后获得“按下按钮”。页面刚刚刷新,我再次输入已经输入的最后一个用户名再次“加载脚本”。我读过的所有问题都没有一个适合我的答案。您看到我的代码有任何问题吗?另外,作为最后的注释;我想使用第一个脚本示例,因为它对我来说更容易理解和使用。

更新

所以,这是可行的。我不知道邮递员生成的代码可以复制。如前所述,我已经用Postman测试了API,并且可以正常工作。这是脚本现在的样子:

$(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);
        });
    })

我实际上从中获得了访问令牌。现在的问题是用户名和密码是硬编码的(不是来自html输入),并且脚本在页面加载后立即运行。有什么想法可以使我仅在按下按钮后才能运行脚本吗?以及如何用输入字段中的值替换硬编码的用户名和密码?邮递员生成的代码带有如此多的\和“,我仍然可以在该行代码中使用变量而不是字符串吗?

我只是尝试将数据重新格式化为{"Username":"someUsername","Password":"somePassword"},但那样行不通,所以我猜\ r \ n是必需的吗?

1 个答案:

答案 0 :(得分:1)

您忘记了表单元素上的方法,尽管serialize方法将获取表单值,但尝试按以下方式设置表单:

{{1}}