aaemnnosttv / wp-cli-login-command

Log in to WordPress with secure passwordless magic links.
https://aaemnnost.tv/wp-cli-commands/login/
MIT License
294 stars 47 forks source link

Invalid login links when working locally #18

Closed ryanjbonnell closed 4 years ago

ryanjbonnell commented 7 years ago

When developing locally, it's a common practice to pull down a fresh copy of the production MySQL database before beginning any new work.

For instance, the production site may be example.com, but the local environment may be setup to use example.dev, as overridden in wp-config.php:

define( 'WP_HOME',    'http://' . $_SERVER['HTTP_HOST'] );
define( 'WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] );

Since it's not always feasible or possible to use a tool like WP Migrate DB Pro or WP-CLI Search & Replace, so often times the wp_options table will still have the production values for siteurl or home:

option_name option_value
site_url http://example.com
home http://example.com

Why does this matter?

By default WP-CLI Login Command uses the value in the database, so when working locally and running a command like wp login as zerocool --launch will return a Magic Login Link similar to:

http://example.com/c39808ec/47c4db-7dc7d05a4d-40b4b4a036

Instead, what is desired is for WP-CLI Login Command to use the local WordPress Site URL, not what is necessarily in the database, such as:

http://example.dev/c39808ec/47c4db-7dc7d05a4d-40b4b4a036

It appears \WP_CLI_Login\LoginCommand::domain() is responsible for determining the URL used for the login links:

 return parse_url(home_url(), PHP_URL_HOST);

While it’s possible to use the home_url() filter to alter this behavior, it would desirable for WP-CLI Login Command to handle this logic ”magically”, so the package and companion plugin could be installed and used with zero configuration.

aaemnnosttv commented 7 years ago

Thanks for your detailed request! The problem is that the login command generates a login link which will only work for the domain it is used on for security purposes. For that reason, the command needs to know the domain ahead of time.

I'm not quite sure if it's possible for the command to resolve what the domain is locally without using core functions. If you defined the WP_HOME with http://example.dev locally it would work as expected.

The current dev-master version of the command includes support for using WP-CLI's --url option. You can use this to set the home url that should be used for generating the login link. This is useful for multisite as well as local dev using something like the wp server command. This will work in your case as well.

Update to the latest version of the command with

wp package install aaemnnosttv/wp-cli-login-command

Then try logging in locally like so:

wp login as zerocool --url=http://example.dev --launch

I realize this probably isn't as zero-configuration as you'd like but I'm not sure it is possible to do much less than that. Please keep in mind that the login command is designed to be usable in production, not just for local development.

ryanjbonnell commented 7 years ago

This is a fantastic idea and just may work.

When running the login command with the url parameter specified, I'm successfully taken to the ”magic link” in my default browser using the correct site URL.

$ wp login as zerocool --url=http://example.dev --launch

However, instead of being automatically logged-in, I'm shown an error message:

screenshot

The attempted magic login has expired or already been used.

Try again perhaps? or Go Home →

Do you have any idea what's causing the error message or how it can be fixed?

Tested with WordPress 4.7.5, WP CLI Login Command Server v1.2 and WP-CLI v1.1.0 on macOS 10.12.5 "Sierra".

aaemnnosttv commented 7 years ago

I'm having a hard time reproducing what you're seeing.

What does home_url() return on example.dev?

ryanjbonnell commented 7 years ago

When placed in functions.php and ran without any hooks, I get the following:

var_dump( home_url() );

string(19) "https://example.dev"
ryanjbonnell commented 7 years ago

While this issue is being sorted out, I opted to use Daniel Bachhuber's One Time Login plugin to allow me to login as any WordPress user from the WP-CLI:

$ wp user one-time-login admin --url=http://example.dev

Taking it one step further, we can pipe the result from One-Time Login and launch our default browser using the "magic" login link for a simple, seamless login experience from the shell:

$ wp user one-time-login admin --url=http://example.dev | grep -Eoh '(http|https)://.*' | xargs open

aaemnnosttv commented 4 years ago

Closing this one out as this seems to be an edge case.

Anyone is free to re-open with more details as to how this can be reproduced on the latest version 👍