WordPress 自带的 RESTful API 内置的身份验证方法是 Cookie Authentication ,登录仪表板时,会生成cookie。为了防止CSRF,需要在请求的地址后面,加上一个 nonce 参数“_wpnonce”。
CSRF请参考:https://javascript.net.cn/article?id=683
nonce生成,参考:https://verytheme.com/archives/136
如果想使用JWT(JSON Web Token),官方建议使用插件 https://wordpress.org/plugins/jwt-authentication-for-wp-rest-api/
但是这个插件只能使用用户名和密码登录,二次开发使用手机号或者验证码登录的话是不可以的,所以自己写了一个大概,可以完成注册、登录和验证。
一,WordPress JWT 用户注册接口
/* -------------------------------------------------------------------------- * * 用户注册接口 http://test.com/wp-json/verytheme/v1/register */ add_action('rest_api_init', 'register_route_hook'); function register_route_hook() { register_rest_route('verytheme/v1', 'register', [ 'methods' => 'POST', 'callback' => 'register_callback' ]); } function register_callback($request) { //获取注册页面提交时候的表单数据 $redirect_to = sanitize_user($_REQUEST['redirect_to']) ? sanitize_user($_REQUEST['redirect_to']) : home_url(); if (!empty($_POST['reg_flag'])) { $error = ''; $sanitized_user_login = sanitize_user($_POST['user_login']); $user_website = sanitize_user($_POST['website']); $user_description = sanitize_user($_POST['description']); $user_nickname = sanitize_user($_POST['nickname']); $user_email = apply_filters('user_registration_email', $_POST['user_email']); // 验证邮箱 if ($user_email == '') { // 一些代码 ... } // 验证用户名 if ($sanitized_user_login == '') { // 一些代码 ... } //验证密码 if (strlen($_POST['user_pass']) < 6) { // 一些代码 ... } if ($error == '') { //验证全部通过进入注册信息添加 $display_name = empty($user_nickname) ? $sanitized_user_login : $user_nickname; $user_pass = $_POST['user_pass']; $user_id = wp_insert_user(array( 'user_login' => $sanitized_user_login, 'user_pass' => $user_pass, 'nickname' => $user_nickname, 'display_name' => $display_name, 'user_email' => $user_email, 'user_url' => $user_website, 'description' => $user_description )); //意外情况判断,添加失败 if (!$user_id) { // 一些代码 ... } } } }
二,WordPress JWT 登录接口
/* -------------------------------------------------------------------------- * * JWT 登录 http://test.com/wp-json/verytheme/v1/login */ add_action('rest_api_init', 'login_route_hook'); function login_route_hook() { register_rest_route('verytheme/v1', 'login', [ 'methods' => 'POST', 'callback' => 'login_callback' ]); } function login_callback($request) { $json = $request->get_json_params(); $username = $json['username']; $password = $json['password']; global $wpdb; $user = $wpdb->get_results($wpdb->prepare("SELECT * FROM wp_users WHERE user_login=%s",$username)); if(!$user){ return new WP_Error( 'jwt_auth_bad_request', '用户名或者密码错误', array( 'status' => 403 ) ); } if(!wp_check_password($password, $user[0]->user_pass)){ return new WP_Error( 'jwt_auth_bad_request', '用户名或者密码错误', array( 'status' => 403 ) ); } $res['token'] = createToken(1); $res['user'] = $user[0]; return $res; } require_once get_template_directory() . "/extends/php-jwt/src/JWT.php"; require_once get_template_directory() . "/extends/php-jwt/src/BeforeValidException.php"; require_once get_template_directory() . "/extends/php-jwt/src/ExpiredException.php"; require_once get_template_directory() . "/extends/php-jwt/src/SignatureInvalidException.php";
三,WordPress JWT 生成JWT Token
/** * 生成JWT Token */ function createToken($user_id) { $time = time(); $payload['iat'] = $time; // 签发时间 $payload['exp'] = $time + 60*1000; // 过期时间 $payload['nbf'] = $time; // 生效时间 $payload['user_id'] = $user_id; // 用户 ID $key = defined('JWT_KEY') ? JWT_KEY : 'default_key'; $token = Firebase\JWT\JWT::encode($payload, $key); return $token; }
四,验证JWT
默认情况下,筛选器使用此选项从请求的cookie(如果可用)中确定当前用户。所有的验证方法钩子都会调用determine_current_user过滤器,包括wp_validate_auth_cookie()。在生成JWT的时候,我们把user_id放入了JWT的Payload中,现在也可以在determine_current_user取出来,像中间价一样。
add_filter('determine_current_user', 'determine_current_user_callback' ); function determine_current_user_callback($user){ $auth = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : false; list($token) = sscanf($auth, 'Bearer %s'); if (!$token) { // echo "fuck"; return 0; } $key = defined('JWT_KEY') ? JWT_KEY : 'default_key'; try { $data = Firebase\JWT\JWT::decode($token, $key, array('HS256')); } catch(Exception $e) { // echo 'Message: ' .$e->getMessage(); return 0; } return $data->user_id ? $data->user_id : 0; }
修改时间 2023-11-14
声明:本站所有文章和图片,如无特殊说明,均为原创发布。商业转载请联系作者获得授权,非商业转载请注明出处。