Orange-OpenSource / hurl

Hurl, run and test HTTP requests with plain text.
https://hurl.dev
Apache License 2.0
12.32k stars 478 forks source link

How to reuse the login logic #2110

Open mangelozzi opened 8 months ago

mangelozzi commented 8 months ago

Problem to solve

In order to query most API's one has to perform authorisation, e.g.:

POST https://example.com/webapi/Token
[FormParams]
userName: {{ username }}@foo.co.za
password: 1234
grant_type: password

HTTP 200
[Captures]
access_token: jsonpath "$['access_token']"

SET access_token = {{ access_token }}

Now either one must copy and paste it at the top of all the related hurl files, or there needs to be a way to share the access_token variable between calls, e.g. hurl --variable username=bob login.hurl need_token_here.hurl

Proposal

I have being going through the docs and can't figure out how to, maybe somethings already exists, if not might be great to update the FAQ to help new commers. If no way exists, maybe one could export the variable to the hurl runner which passes them into the next session?

RyanEager-TensorIoT commented 8 months ago

I've been facing this same issue.

A more generic solution would be creating the ability to call a Hurl file within a Hurl file.

users.hurl

hurl auth.hurl --variables-file vars.env
# ^ This would run the file and with captures passed back. 

#Get list of users
GET {{host}}/users
Authorization: Bearer {{cognitoIdToken}}

auth.hurl

# Get Cognito Tokens
POST https://cognito-idp.us-west-2.amazonaws.com/
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Content-Type: application/x-amz-json-1.1
{
    "AuthParameters": {
        "USERNAME": "{{username}}",
        "PASSWORD": "{{password}}"
    },
    "AuthFlow": "USER_PASSWORD_AUTH",
    "ClientId": "{{clientId}}"
}

HTTP 200
[Captures]
cognitoAccessToken: jsonpath "$.AuthenticationResult.AccessToken"
cognitoIdToken: jsonpath "$.AuthenticationResult.IdToken"
SilenLoc commented 7 months ago

I would also like to hurl to implement something like that.

For now I created a tool only for that, https://github.com/SilenLoc/aditus, it only works with Auth0 or equal token endpoints with pw flow. (not everything in the wild is OIDC compliant)

Obvs. you can use pure curl, take the token with jq from the response, then assign it to HURL_access_token={{token}}

I made and will continue to improve the tool to integrate with Hurl. For now it supports creating a env file with = and returning the token raw or the whole answer.

Taoaozw commented 3 months ago

I've been facing this same issue.我一直面临同样的问题。

A more generic solution would be creating the ability to call a Hurl file within a Hurl file.更通用的解决方案是创建在 Hurl 文件中调用 Hurl 文件的功能。

users.hurl 用户.hurl

hurl auth.hurl --variables-file vars.env
# ^ This would run the file and with captures passed back. 

#Get list of users
GET {{host}}/users
Authorization: Bearer {{cognitoIdToken}}

auth.hurl 授权文件

# Get Cognito Tokens
POST https://cognito-idp.us-west-2.amazonaws.com/
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Content-Type: application/x-amz-json-1.1
{
    "AuthParameters": {
        "USERNAME": "{{username}}",
        "PASSWORD": "{{password}}"
    },
    "AuthFlow": "USER_PASSWORD_AUTH",
    "ClientId": "{{clientId}}"
}

HTTP 200
[Captures]
cognitoAccessToken: jsonpath "$.AuthenticationResult.AccessToken"
cognitoIdToken: jsonpath "$.AuthenticationResult.IdToken"

I think it's great.

danbrotherston commented 3 months ago

This seems like a natural use case for the intended purpose of this tool, and the flow described of including files is a reasonable method of composition. But either way, definitely need some support for this login workflow in order to use this tool.

dompie commented 3 months ago

I was looking for a way to test different tokens for different request parameters. I could reuse variables in the following way. Hope it helps:

token.hurl

GET {{host}}/api/get/token/for/abcdef12345
HTTP 200

[Captures]
token: jsonpath "$.data.token"

[Asserts]
jsonpath "$.data.token" matches "^[a-zA-Z0-9]{10}csrf$"

GET {{host}}/api/get/token/for/abc123
HTTP 200
[Asserts]
jsonpath "$.data.token" not matches "{{token}}"