使用 wp_set_auth_cookie 没有任何钩子
using wp_set_auth_cookie with out any hook
WordPress 版本 4.7.5
我正在从 Instagram 注册新用户,我可以成功注册新用户。注册后我正在尝试登录用户。
I can use hook, but would like better solution than the dirty one, I
have posted as that will be totally unuseful .
if( $user_created ) {
$new_user = get_user_by( 'id', $user_created );
//$loggedin = programmatic_login( $new_user->user_login );
//ob_start();
if ( !is_user_logged_in() ) {
wp_clear_auth_cookie();
wp_set_current_user( $user_created, $new_user->user_login );
wp_set_auth_cookie( $user_created, true );
do_action( 'wp_login', $new_user->user_login );
// wp_safe_redirect(site_url() . '/profile/');
// exit;
// $redirect_to=user_admin_url();
// wp_safe_redirect($redirect_to);
// exit();
}
//ob_end_clean();
} ?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo site_url() . '/profile/'; ?>";});</script> <?php
还尝试使用来自另一个 post 的自定义 programmatic_login 函数。
如果我尝试 var_dump
wp_get_current_user()
和 $_COOKIE
低于此,我将获得 wp_get_current_user()
的用户对象和 [=18 的 array(1) { ["wordpress_test_cookie"]=> string(15) "WP Cookie check" }
=].
重要编辑
该代码在一个函数中,该函数与一个钩子挂钩,该函数在页眉显示后的页面中调用,因此我们不能在这里使用 init。任何其他方式也因为这个 wp_safe_redirect()
或 header('Location: ')
也不起作用。
关于我刚刚尝试的重要更新
肮脏的工作
当我从 Instagram 登录创建用户时,成功创建后我将用户重定向到一个页面,其中包含类似 ?user_id=$inserted_id
的获取参数,在 wp 挂钩上,我尝试获取 GET['user_id']
和记录了它并且它起作用了,试图找到合适的解决方案。
if ( $wpdb->insert_id ){ //that is registration with instagram
?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo get_bloginfo('url') . '/profile/?id=' . $wpdb->insert_id; ?>";});</script>
<?php
}
然后
add_action( 'wp', 'login_current_user' );
function login_current_user(){
if ( is_page() && get_the_id() == 863 ){
if ( isset( $_GET['id'] ) ){
if ( !is_user_logged_in() ) {
$user_id = $_GET['id'];
$user = get_user_by( 'id', $user_id );
wp_clear_auth_cookie();
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id, true );
do_action( 'wp_login', $user->user_login );
if ( is_user_logged_in() ){
$redirect_to=site_url() . '/profile';
wp_safe_redirect($redirect_to);
exit();
}
}
}
}
}
Proble with dirty trick. If the id
we are passing as get parameter
exists in wp_users table then with no verification that will be logged
in .
更新
我在重定向到个人资料页面之前创建了一个 user_meta 并在验证后登录用户并删除了用户元,就像 OTP 一样。如果可能,努力让它变得更好。
代码下方:-
if ( $wpdb->insert_id ){ //that is registration with instagram
$temporary_token = sha1(rand());
update_user_meta( $wpdb->insert_id, 'temporary_token', $temporary_token);
?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo get_bloginfo('url') . '/profile/?id=' . $wpdb->insert_id . '&token=' . $temporary_token; ?>";});</script>
<?php
}
然后
add_action( 'wp', 'login_current_user' );
function login_current_user(){
if ( is_page() && get_the_id() == 863 ){
if ( isset( $_GET['id'] ) ){
if ( !is_user_logged_in() ) {
$user_id = $_GET['id'];
$user = get_user_by( 'id', $user_id );
if ( $_GET['token'] == get_user_meta( $user_id, 'temporary_token', true ) ){
delete_user_meta( $user_id, 'temporary_token', $_GET['token'] );
wp_clear_auth_cookie();
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id, true );
do_action( 'wp_login', $user->user_login );
if ( is_user_logged_in() ){
$redirect_to=site_url() . '/profile';
wp_safe_redirect($redirect_to);
exit();
}
}
}
}
}
}
如果 headers 在 wp_clear_auth_cookie()
或 wp_set_auth_cookie()
被调用之前发送,那么两者都不会起作用,因为它们都依赖于 PHP 的 setcookie
函数。 after_setup_theme
操作将在 headers 发送之前发生,因此挂钩并在那里设置 cookie 应该可以解决问题。
function myPlugin_createUser(){
// Probably need to put code that creates user here too otherwise $user_created will never return true
if( $user_created ) {
$new_user = get_user_by( 'id', $user_created );
if ( !is_user_logged_in() ) {
wp_clear_auth_cookie();
wp_set_current_user( $user_created, $new_user->user_login );
wp_set_auth_cookie( $user_created, true );
do_action( 'wp_login', $new_user->user_login );
}
}
}
add_action( 'after_setup_theme', 'myPlugin_createUser' );
更新:
如果您在触发 createUser
函数之前输出视图元素,它将无法工作,因此我们需要确保它们 运行 完全相互独立。下面我整理了一个简单的例子来说明如何实现这一点——我们输出一个 link 的视图,它传递一个 GET 参数,这个参数由插件和 运行 之前的动作获取呈现任何内容,允许我们设置 cookie。
my-plugin.php
// Note: you'll need to include a completed version of myPlugin_createUser() function as above for these examples to work
add_shortcode( 'my-plugin', function() {
// I've used a GET request for simplicity- a form + POST request may be more practical for your purposes and will prevent caching issues.
echo "<a href='?my_plugin_login_user=1'>Login</a>";
});
// Check for our GET parameter
if( isset( $_GET['my_plugin_login_user'] ) ) {
// Nothing should be rendered yet as plugin template hasn't even started loading yet so cookies should set fine
add_action( 'plugins_loaded', 'myPlugin_createUser' );
}
page-my-template.php
<div> ...
<?php
do_shortcode( 'my-plugin' );
?>
</div>
更新二:
如果使用 Instagram 身份验证 API,概述的显式流程 https://www.instagram.com/developer/authentication/(下面使用的大多数示例都取自那里)可能是最好的方法。下面我将简要介绍 运行 如何实施它。其中大部分是从那里提取的,并添加了注释。
您可以将 WordPress 用户 ID 作为参数包含在回调 URL 中,或者如果用户尚未创建并且您需要维护状态,那么您将需要生成一个临时令牌您可以稍后使用与所述数据相关联的数据或存储该数据客户端(如果它不敏感)这可能更容易和更好,因为它不需要用户登录即可运行。
用户随后会登录
关于这一步没什么可说的 - 如果发生错误,他们将被重定向到 http://your-redirect-uri?error=access_denied&error_reason=user_denied&error_description=The+user+denied+your+request
如果登录成功,用户将被重定向到 http://your-redirect-uri?code=CODE
CODE
在重定向上传回 URL 我们可以兑换访问令牌。
因此,从这里开始,我们可以通过多种方式来处理它,但本质上,我们需要的是重定向的端点,我们有足够的控制权在任何 HTTP 响应之前发送 HTTP headers body 被发送。
解决这个问题的方法(不是详尽的列表):
- 允许有条件地挂钩 Instagram 授权页面(如您的示例所示)。这样做的好处是不需要额外的重定向。
- 自定义页面模板
- 手动引导 WordPress 的外部脚本执行我们需要的操作,然后重定向回
所以现在一旦我们设置了端点,我们就需要兑换 CODE
以获得访问令牌。改编自 https://gist.github.com/arturmamedov/7f5a90b85a20e06e344ebb88dc898d25
$uri = 'https://api.instagram.com/oauth/access_token';
$data = [
'client_id' => '213esdaedasdasd12...YOUR_CLIENT_ID',
'client_secret' => 'a8b4aaf06c0da310...YOUR_CLIENT_SECRET',
'grant_type' => 'authorization_code',
'redirect_uri' => 'http://www.YOUR_REDIRECT_URL.it', // The exact redirect URL as used previously
'code' => $_GET['code']
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri); // uri
curl_setopt($ch, CURLOPT_POST, true); // POST
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // POST DATA
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // RETURN RESULT true
curl_setopt($ch, CURLOPT_HEADER, 0); // RETURN HEADER false
curl_setopt($ch, CURLOPT_NOBODY, 0); // NO RETURN BODY false / we need the body to return
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // VERIFY SSL HOST false
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // VERIFY SSL PEER false
$result = json_decode(curl_exec($ch));
$result 将是 JSON 响应的 object 表示:
{
"access_token": "fb2e77d.47a0479900504cb3ab4a1f626d174d2d",
"user": {
"id": "1574083",
"username": "snoopdogg",
"full_name": "Snoop Dogg",
"profile_picture": "..."
}
}
从这里我们只需使用 WordPress 创建我们的 user/authenticate 并重定向到所需的 page/render 模板(如果通过条件挂钩处理则无需重定向)并在需要时恢复页面状态。
WordPress 版本 4.7.5
我正在从 Instagram 注册新用户,我可以成功注册新用户。注册后我正在尝试登录用户。
I can use hook, but would like better solution than the dirty one, I have posted as that will be totally unuseful .
if( $user_created ) {
$new_user = get_user_by( 'id', $user_created );
//$loggedin = programmatic_login( $new_user->user_login );
//ob_start();
if ( !is_user_logged_in() ) {
wp_clear_auth_cookie();
wp_set_current_user( $user_created, $new_user->user_login );
wp_set_auth_cookie( $user_created, true );
do_action( 'wp_login', $new_user->user_login );
// wp_safe_redirect(site_url() . '/profile/');
// exit;
// $redirect_to=user_admin_url();
// wp_safe_redirect($redirect_to);
// exit();
}
//ob_end_clean();
} ?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo site_url() . '/profile/'; ?>";});</script> <?php
还尝试使用来自另一个 post 的自定义 programmatic_login 函数。
如果我尝试 var_dump
wp_get_current_user()
和 $_COOKIE
低于此,我将获得 wp_get_current_user()
的用户对象和 [=18 的 array(1) { ["wordpress_test_cookie"]=> string(15) "WP Cookie check" }
=].
重要编辑
该代码在一个函数中,该函数与一个钩子挂钩,该函数在页眉显示后的页面中调用,因此我们不能在这里使用 init。任何其他方式也因为这个 wp_safe_redirect()
或 header('Location: ')
也不起作用。
关于我刚刚尝试的重要更新
肮脏的工作
当我从 Instagram 登录创建用户时,成功创建后我将用户重定向到一个页面,其中包含类似 ?user_id=$inserted_id
的获取参数,在 wp 挂钩上,我尝试获取 GET['user_id']
和记录了它并且它起作用了,试图找到合适的解决方案。
if ( $wpdb->insert_id ){ //that is registration with instagram
?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo get_bloginfo('url') . '/profile/?id=' . $wpdb->insert_id; ?>";});</script>
<?php
}
然后
add_action( 'wp', 'login_current_user' );
function login_current_user(){
if ( is_page() && get_the_id() == 863 ){
if ( isset( $_GET['id'] ) ){
if ( !is_user_logged_in() ) {
$user_id = $_GET['id'];
$user = get_user_by( 'id', $user_id );
wp_clear_auth_cookie();
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id, true );
do_action( 'wp_login', $user->user_login );
if ( is_user_logged_in() ){
$redirect_to=site_url() . '/profile';
wp_safe_redirect($redirect_to);
exit();
}
}
}
}
}
Proble with dirty trick. If the
id
we are passing as get parameter exists in wp_users table then with no verification that will be logged in .
更新
我在重定向到个人资料页面之前创建了一个 user_meta 并在验证后登录用户并删除了用户元,就像 OTP 一样。如果可能,努力让它变得更好。
代码下方:-
if ( $wpdb->insert_id ){ //that is registration with instagram
$temporary_token = sha1(rand());
update_user_meta( $wpdb->insert_id, 'temporary_token', $temporary_token);
?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo get_bloginfo('url') . '/profile/?id=' . $wpdb->insert_id . '&token=' . $temporary_token; ?>";});</script>
<?php
}
然后
add_action( 'wp', 'login_current_user' );
function login_current_user(){
if ( is_page() && get_the_id() == 863 ){
if ( isset( $_GET['id'] ) ){
if ( !is_user_logged_in() ) {
$user_id = $_GET['id'];
$user = get_user_by( 'id', $user_id );
if ( $_GET['token'] == get_user_meta( $user_id, 'temporary_token', true ) ){
delete_user_meta( $user_id, 'temporary_token', $_GET['token'] );
wp_clear_auth_cookie();
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id, true );
do_action( 'wp_login', $user->user_login );
if ( is_user_logged_in() ){
$redirect_to=site_url() . '/profile';
wp_safe_redirect($redirect_to);
exit();
}
}
}
}
}
}
如果 headers 在 wp_clear_auth_cookie()
或 wp_set_auth_cookie()
被调用之前发送,那么两者都不会起作用,因为它们都依赖于 PHP 的 setcookie
函数。 after_setup_theme
操作将在 headers 发送之前发生,因此挂钩并在那里设置 cookie 应该可以解决问题。
function myPlugin_createUser(){
// Probably need to put code that creates user here too otherwise $user_created will never return true
if( $user_created ) {
$new_user = get_user_by( 'id', $user_created );
if ( !is_user_logged_in() ) {
wp_clear_auth_cookie();
wp_set_current_user( $user_created, $new_user->user_login );
wp_set_auth_cookie( $user_created, true );
do_action( 'wp_login', $new_user->user_login );
}
}
}
add_action( 'after_setup_theme', 'myPlugin_createUser' );
更新:
如果您在触发 createUser
函数之前输出视图元素,它将无法工作,因此我们需要确保它们 运行 完全相互独立。下面我整理了一个简单的例子来说明如何实现这一点——我们输出一个 link 的视图,它传递一个 GET 参数,这个参数由插件和 运行 之前的动作获取呈现任何内容,允许我们设置 cookie。
my-plugin.php
// Note: you'll need to include a completed version of myPlugin_createUser() function as above for these examples to work
add_shortcode( 'my-plugin', function() {
// I've used a GET request for simplicity- a form + POST request may be more practical for your purposes and will prevent caching issues.
echo "<a href='?my_plugin_login_user=1'>Login</a>";
});
// Check for our GET parameter
if( isset( $_GET['my_plugin_login_user'] ) ) {
// Nothing should be rendered yet as plugin template hasn't even started loading yet so cookies should set fine
add_action( 'plugins_loaded', 'myPlugin_createUser' );
}
page-my-template.php
<div> ...
<?php
do_shortcode( 'my-plugin' );
?>
</div>
更新二: 如果使用 Instagram 身份验证 API,概述的显式流程 https://www.instagram.com/developer/authentication/(下面使用的大多数示例都取自那里)可能是最好的方法。下面我将简要介绍 运行 如何实施它。其中大部分是从那里提取的,并添加了注释。
您可以将 WordPress 用户 ID 作为参数包含在回调 URL 中,或者如果用户尚未创建并且您需要维护状态,那么您将需要生成一个临时令牌您可以稍后使用与所述数据相关联的数据或存储该数据客户端(如果它不敏感)这可能更容易和更好,因为它不需要用户登录即可运行。
用户随后会登录
关于这一步没什么可说的 - 如果发生错误,他们将被重定向到 http://your-redirect-uri?error=access_denied&error_reason=user_denied&error_description=The+user+denied+your+request
如果登录成功,用户将被重定向到 http://your-redirect-uri?code=CODE
CODE
在重定向上传回 URL 我们可以兑换访问令牌。
因此,从这里开始,我们可以通过多种方式来处理它,但本质上,我们需要的是重定向的端点,我们有足够的控制权在任何 HTTP 响应之前发送 HTTP headers body 被发送。
解决这个问题的方法(不是详尽的列表):
- 允许有条件地挂钩 Instagram 授权页面(如您的示例所示)。这样做的好处是不需要额外的重定向。
- 自定义页面模板
- 手动引导 WordPress 的外部脚本执行我们需要的操作,然后重定向回
所以现在一旦我们设置了端点,我们就需要兑换 CODE
以获得访问令牌。改编自 https://gist.github.com/arturmamedov/7f5a90b85a20e06e344ebb88dc898d25
$uri = 'https://api.instagram.com/oauth/access_token';
$data = [
'client_id' => '213esdaedasdasd12...YOUR_CLIENT_ID',
'client_secret' => 'a8b4aaf06c0da310...YOUR_CLIENT_SECRET',
'grant_type' => 'authorization_code',
'redirect_uri' => 'http://www.YOUR_REDIRECT_URL.it', // The exact redirect URL as used previously
'code' => $_GET['code']
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri); // uri
curl_setopt($ch, CURLOPT_POST, true); // POST
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // POST DATA
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // RETURN RESULT true
curl_setopt($ch, CURLOPT_HEADER, 0); // RETURN HEADER false
curl_setopt($ch, CURLOPT_NOBODY, 0); // NO RETURN BODY false / we need the body to return
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // VERIFY SSL HOST false
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // VERIFY SSL PEER false
$result = json_decode(curl_exec($ch));
$result 将是 JSON 响应的 object 表示:
{
"access_token": "fb2e77d.47a0479900504cb3ab4a1f626d174d2d",
"user": {
"id": "1574083",
"username": "snoopdogg",
"full_name": "Snoop Dogg",
"profile_picture": "..."
}
}
从这里我们只需使用 WordPress 创建我们的 user/authenticate 并重定向到所需的 page/render 模板(如果通过条件挂钩处理则无需重定向)并在需要时恢复页面状态。