安装完MySQL后,我们通常添加拥有相应权限的普通用户用来访问数据库。在使用普通用户(假设为tom)本地登录数据库的时候,经常会出现无法登录的情况,但是从其他的mysql客户端却可以登录。在本地使用tom用户不输入密码可以登陆成功。

  登陆成功后执行如下命令

  SELECT USER(), CURRENT_USER();

+-------------------------+-----------------------+
     | USER()                        | CURRENT_USER()  |
     +-------------------------+-----------------------+
     | tom@localhost           | @localhost                |
     +-------------------------+-----------------------+

> USER()函数返回你在客户端登陆时指定的用户名和主机名
> CURRENT_USER()函数返回的是MySQL使用授权表中的哪个用户来认证你的登录请求

  上述结果表明使用'tom'@'localhost'这个账户登录数据库(因为在本地登陆时没指定主机,默认是以localhost登录),但是数据库使用的是''@'localhost'这个账户来进行登录认证,而''@'localhost'这个匿名用户是没有密码的,因此输入空密码登录成功。但是登录后,所对应的用户的匿名用户。

  一般在MySQL在安装完毕后,使用mysql_install_db这个脚本生成授权表,会默认创建''@'localhost'这个匿名用户。正是因为这个匿名用户,影响了其他用户从本地登录的认证。

MySQL是如何进行用户身份认证呢?

一、当用户从客户端请求登陆时,MySQL将授权表中的条目与客户端所提供的条目进行比较,包括用户的用户名,密码和主机。授权表中的Host字段是可以使用通配符作为模式进行匹配的,如test.example.com, %.example.com, %.com和%都可以匹配test.example.com这个主机。授权表中的User字段不允许使用模式匹配,但是可以有一个空字符的用户名代表匿名用户,并且空字符串可以匹配所有的用户名,就像通配符一样。 当user表中的Host和User有多个值可以匹配客户端提供的主机和用户名时,MySQL将user表读入内存,并且按照一定规则排序,按照排序规则读取到的第一个匹配客户端用户名和主机名的条目对客户端进行身份验证。

二、排序规则:对于Host字段,按照匹配的精确程度进行排序,越精确的排序越前,例如当匹配test.example.com这个主机时, %.example.com比%.com更精确,而test.example.com比%.example.com更精确。对于User字段,非空的字符串用户名比空字符串匹配的用户名排序更靠前。 User和Host字段都有多个匹配值,MySQL使用主机名排序最前的条目,在主机名字段相同时再选取用户名排序更前的条目。因此,如果User和Host字段都有多个匹配值,主机名最精确匹配的条目被用户对用户进行认证。

mysql> select host,user from mysql.user;

+--------------------------+-------+

| host                                   | user  |

+--------------------------+-------+

| %                                       | tom   |

| 127.0.0.1                          | root   |

| ::1                                      | root   |

| localhost                           | root   |

| localhost                           |          |

| promote.cache-dns.local |         |

| promote.cache-dns.local | root  |

+---------------------------+-------+

根据上面的匹配规则以及用户查询结果:

  使用tom在本机登录数据库时,不指定-h参数默认为localhost主机登录,而在MySQL中有两个匹配的条目:'tom'@'%'  和 ''@'localhost'

(匿名用户能够匹配的原因上面说过,空字符串可以匹配所有的用户名),根据MySQL认证时的排序规则,第一个条目的用户名排序更前,第二个条目的主机名更精确排序更前。而MySQL会优先使用主机名排序第一的条目进行身份认证,因此''@'localhost'被用户对客户端进行认证。所以只有使用匿名用户的空密码才能登录进数据库。

解决的方法:删除匿名用户(仅仅为了安全也有这个必要)

为什么root用户不会受影响,而只有普通用户不能从本地登录?

因为mysql_install_db脚本会在授权表中生成'root'@'localhost'这个账户。同样的,使用root登录MySQL 时,'root'@'localhost'和''@'localhost'都能匹配登录的账户,但是根据排序规则,主机名相同,而用户名非空字符串优先,因此'root'@'localhost'这个条目的排序更靠前。使用root本地登录是不会被匿名用户遮盖。

本文转载自http://www.linuxidc.com/Linux/2015-03/115164.htm,仅作学习记录以备查阅,稍作整理。

MySQL用户无法登陆问题的更多相关文章

  1. MySQL用户远程登陆

    默认情况下,root用户是不具备远程登录的权限. 1.切换mysql表,查看当前用户信息 select host,user from user where user = 'root' 2.给用户进行授 ...

  2. mysql 查看当前登陆用户匹配原则及权限user()与current_user()

    Mysql在进行登陆时,会去匹配mysql库中的user表,并赋予相应的权限,但是怎么知道我们当时的登陆的用户名及相应的权限呢? 在Mysql中,有两个函数,一个是user(),一个是current_ ...

  3. mysql新增用户无法登陆问题解决ERROR 1045 (28000)

    mysql增加新用户无法登陆解决方法 ERROR 1045 (28000): Access denied for user 'appadmin'@'localhost' (using password ...

  4. mysql用户的创建

    MySQL是采用c/s方式的,需要客户端登录服务器,那么可以登录账号叫做用户,这些用户的信息都存储在mysql数据库(mysql安装时默认有的一个数据库)中的user表中, 比如用户的名称,用户的密码 ...

  5. MySQL用户管理及SQL语句详解

    1.1 MySQL用户管理 1.1.1 用户的定义 用户名+主机域 mysql> select user,host,password from mysql.user; +--------+--- ...

  6. mysql用户授权及数据备份恢复

    用户授权与权限撤销 修改数据库管理员从本机登陆的密码测试: mysqladmin -hlocalhost -uroot -p password "新密码" Enter passwo ...

  7. 库增删该查,表增删该查,记录增删该查,表与表关系(多对多,多对一,一对一),mysql用户管理

    库增删该查 增加库 create database db1 create database db1 charset="gbk 查看库 show databases 查看所有库 show cr ...

  8. Mysql 用户和权限

    创建用户 CREATE USER '用户名'@'localhost' IDENTIFIED BY '密码'; 删除用户 DROP USER '用户名'@'localhost'; 权限列表 ALL 或 ...

  9. mysql 用户及权限管理 小结

    MySQL 默认有个root用户,但是这个用户权限太大,一般只在管理数据库时候才用.如果在项目中要连接 MySQL 数据库,则建议新建一个权限较小的用户来连接. 在 MySQL 命令行模式下输入如下命 ...

随机推荐

  1. mybaits 框架运用

    支持普通 SQL 查询,存储过程和高级映射的ORM持久层框架.以一 个 SqlSessionFactory 对象的实例为核心. 从 XML 中构建 SqlSessionFactory configur ...

  2. nginx的pass_proxy遇到的坑

    Pass_proxy走内网,被请求方的php使用remote_addr得到就是转发机器的内网地址,如192.168.10.141这样的.走外网,被请求方php的remote_addr得到就是转发机器的 ...

  3. Python读写excel

    #-*- coding:utf-8 -*- #__author__ = 'liu-ke' import xlrd from xlutils.copy import copy mybook = xlrd ...

  4. loadrunner11中java vuser引用jar包

    1.创建工程,新建类,HelloWorld.java,代码如下: package com.liuke; public class HelloWorld { public String getHello ...

  5. rabbitmq启动异常之error,{not_a_dets_file recovery.dets

    中午,公司群里面测试人员@笔者说,早上测试服务器异常,MQ起不来,重启os了也起不来,报错,上去看下了早上又因为内存oom被内核killed了,启动了下,确实启动报错,erl vm进程起来了,但是be ...

  6. Reapp - 下一代的 Hybrid App 开发框架

    Reapp 与 React Native 有着惊人的相似之处,二者都使用 React 来创建应用程序用户界面的框架.然而,在底层机制上这两个框架之间却具有明显的哲学差异.React Native 将 ...

  7. Hybrid框架UI重构之路:四、分而治之

    上文回顾:Hybird框架UI重构之路:三.工欲善其事,必先利其器 上一篇文章有说到less.grunt这两个工具,是为了css.js分模块使用的.UI框架提供给使用者的时候,是一个大的xxx.js. ...

  8. 从零开始,做一个NodeJS博客(三):API实现-加载网易云音乐听歌排行

    标签: NodeJS 0 研究了一天,翻遍了GitHub上各种网易云API库,也没有找到我想要的听歌排行API,可能这功能比较小众吧.但收获也不是没有,在 这里 明白了云音乐API加密的凶险,我等蒟蒻 ...

  9. 使用 jQuery Mockjax 插件模拟 Ajax 请求

    在实际的开发过程中,前端后台协商好了统一的接口,就各自开始自己的任务了.这时候我有这么一个 Ajax 请求需要从后台获取数据: $.ajax({ url: '/products/' }).done(f ...

  10. JavaScript 开发者经常忽略或误用的七个基础知识点(转)

    JavaScript 本身可以算是一门简单的语言,但我们也不断用智慧和灵活的模式来改进它.昨天我们将这些模式应用到了 JavaScript 框架中,今天这些框架又驱动了我们的 Web 应用程序.很多新 ...