Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): add fortify login route to retrieve api key #2455

Closed

Conversation

wescopeland
Copy link
Member

@wescopeland wescopeland commented May 20, 2024

The PR adds a new V2 web API route:

POST https://localhost:64000/api/v2/login
# Request Payload
{
  "username": "MyUsername"
  "password": "MyPassword"
}
# Response Payload
{
  "webApiKey": "XXXXXXXXXXXXXXXXXXXXXXXXXX"
}

This route will conceivably allow emulation front-ends to exchange user credentials for a user's web API key, ideally to ween them off the Connect API (for which they're currently exchanging credentials for a connect token).

Security Considerations:

  • Error messages are intentionally obtuse.
  • The route is secured by Fortify (just like our web logins), not authenticateFromPassword().
  • The route uses the same rate limiter as the site's login page.

@wescopeland wescopeland requested a review from a team May 20, 2024 22:28
@wescopeland
Copy link
Member Author

Documented at RetroAchievements/api-docs#46.

return response()->json(['webApiKey' => $user->api_token]);
}

return response()->json(['error' => 'Something went wrong'], 400);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the necessity to not reveal too much, but would it be correct to return "Invalid user/password" here like we do for connect?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know @luchaos wants to move to a response structure more in line with the official JSON API docs: https://discord.com/channels/476211979464343552/757767535293890682/1132370669938671758.

I think a response formatted in that manner would look like:

{
    "errors": [
        {
            "status": "401",
            "code": "invalid_credentials",
            "title": "Invalid username/password",
        }
    ]
}

I would really like to get his feedback on anything we're going to call V2 of the API.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connect also has a secondary "access denied" error if the credentials are valid, but the account's email address hasn't yet been verified.

Copy link
Member Author

@wescopeland wescopeland May 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative to putting this in the V2 API namespace might be to return something like APIKey from r=login2. I would be happy to put this in the V1 Web API, but it's designed to only accept authenticated GET requests.

@@ -34,4 +36,25 @@ public function users(Request $request): JsonResponse
'data' => $request->input(),
], 501);
}

public function login(Request $request): JsonResponse
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to add unit tests for this? I would really like everything in the V2 API to have good test coverage.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - certainly. Pending if we decide to keep this in here, I'm happy to add code coverage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants