• 权限管理,pymysql模块


    权限管理

    权限管理重点

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

    在 MySQL 命令行模式下输入如下命令可以为 MySQL 创建一个新用户:

    create user "账户名"@"主机名" identified by 密码
    create user "tom"@"localhost" identified by "123";

    新用户创建完成,但是此刻如果以此用户登陆的话,会报错,因为我们还没有为这个用户分配相应权限,分配权限的命令如下:

    授予所有数据库所有表的所有权限给jerry这个用户  并允许jerry在任意一台电脑登录
    如果用户不存在会自动创建
    grant all on *.* to "jerry"@"%" identified by  "123" with grant option;
    
    with grant option这个用户可以将拥有的权限授予别人

    授予username用户在所有数据库上的所有权限。

    如果此时发现刚刚给的权限太大了,如果我们只是想授予它在某个数据库上的权限,那么需要切换到root 用户撤销刚才的权限,重新授权:

    授予day45数据库所有表的所有权限给jack这个用户 并允许jerry在任意一台电脑登录

    grant all on  day45.* to "jack"@"%" identified by  "123";

    授予day45数据库的emp表的所有权限给rose这个用户 并允许jerry在任意一台电脑登录

    grant all on day45.emp to "rose"@"%" identified by "123";

    授予day45数据库的emp表的name字段的查询权限给maria这个用户 并允许jerry在任意一台电脑登录

    grant select(name) on day45.emp to "maria"@"%" identified by "123";

    另外每当调整权限后,通常需要执行以下语句刷新权限:

    flush privileges;

    收回权限

    REVOKE all privileges [column] on db.table from user@"host";

    如何授权就如何收回 因为不同权限信息存到不同的表中

    REVOKE all privileges on day45.emp from maria@"%"; 

    当你在云服务器部署了 mysql环境时 你的程序无法直接连接到服务器 需要授予在任意一台电脑登录的权限

    grant all on *.* to "jerry"@"%" identified by "123" with grant option;

    删除刚才创建的用户:

    DROP USER 用户名@localhost;

    仔细上面几个命令,可以发现不管是授权,还是撤销授权,都要指定响应的host(即 @ 符号后面的内容),因为以上及格命令实际上都是在操作mysql 数据库中的user表,可以用如下命令查看相应用户及对应的host:

    SELECT User, Host FROM user;

    权限表

    MySQL服务器通过MySQL权限表来控制用户对数据库的访问,MySQL权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些MySQL权限表分别user,db,table_priv,columns_priv和host。下面分别介绍一下这些表的结构和内容:
    user权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的。
    db权限表:记录各个帐号在各个数据库上的操作权限。
    table_priv权限表:记录数据表级的操作权限。
    columns_priv权限表:记录数据列级的操作权限。
    host权限表:配合db权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。

    权限列表

    ALTER: 修改表和索引。
    CREATE: 创建数据库和表。
    DELETE: 删除表中已有的记录。
    DROP: 抛弃(删除)数据库和表。
    INDEX: 创建或抛弃索引。
    INSERT: 向表中插入新行。
    REFERENCE: 未用。
    SELECT: 检索表中的记录。
    UPDATE: 修改现存表记录。
    FILE: 读或写服务器上的文件。
    PROCESS: 查看服务器中执行的线程信息或杀死线程。
    RELOAD: 重载授权表或清空日志、主机缓存或表缓存。
    SHUTDOWN: 关闭服务器。
    ALL: 所有权限,ALL PRIVILEGES同义词。
    USAGE: 特殊的 "无权限" 权限。
    用 户账户包括 "username" 和 "host" 两部分,后者表示该用户被允许从何地接入。tom@'%' 表示任何地址,默认可以省略。还可以是 "tom@192.168.1.%"、"tom@%.abc.com" 等。数据库格式为 db@table,可以是 "test.*" 或 "*.*",前者表示 test 数据库的所有表,后者表示所有数据库的所有表。
    子句 "WITH GRANT OPTION" 表示该用户可以为其他用户分配权限。 

    补充知识

    grant和revoke可以在几个层次上控制访问权限
    1,整个服务器,使用 grant ALL 和revoke ALL
    2,整个数据库,使用on database.*
    3,特点表,使用on database.table
    4,特定的列
    5,特定的存储过程

    user表中host列的值的意义
    % 匹配所有主机
    localhost localhost不会被解析成IP地址,直接通过UNIXsocket连接
    127.0.0.1 会通过TCP/IP协议连接,并且只能在本机访问;
    ::1 ::1就是兼容支持ipv6的,表示同ipv4的127.0.0.1

    grant 普通数据用户,查询、插入、更新、删除 数据库中所有表数据的权利。
    grant select on testdb.* to common_user@’%’
    grant insert on testdb.* to common_user@’%’
    grant update on testdb.* to common_user@’%’
    grant delete on testdb.* to common_user@’%’
    或者,用一条 MySQL 命令来替代:
    grant select, insert, update, delete on testdb.* to common_user@’%’
    grant 数据库开发人员,创建表、索引、视图、存储过程、函数。。。等权限。
    grant 创建、修改、删除 MySQL 数据表结构权限。
    grant create on testdb.* to developer@’192.168.0.%’;
    grant alter on testdb.* to developer@’192.168.0.%’;
    grant drop on testdb.* to developer@’192.168.0.%’;
    grant 操作 MySQL 外键权限。
    grant references on testdb.* to developer@’192.168.0.%’;
    grant 操作 MySQL 临时表权限。
    grant create temporary tables on testdb.* to developer@’192.168.0.%’;
    grant 操作 MySQL 索引权限。
    grant index on testdb.* to developer@’192.168.0.%’;
    grant 操作 MySQL 视图、查看视图源代码 权限。
    grant create view on testdb.* to developer@’192.168.0.%’;
    grant show view on testdb.* to developer@’192.168.0.%’;
    grant 操作 MySQL 存储过程、函数 权限。
    grant create routine on testdb.* to developer@’192.168.0.%’; -- now, can show procedure status
    grant alter routine on testdb.* to developer@’192.168.0.%’; -- now, you can drop a procedure
    grant execute on testdb.* to developer@’192.168.0.%’;
    grant 普通 DBA 管理某个 MySQL 数据库的权限。
    grant all privileges on testdb to dba@’localhost’
    其中,关键字 “privileges” 可以省略。
    grant 高级 DBA 管理 MySQL 中所有数据库的权限。
    grant all on *.* to dba@’localhost’

    MySQL grant 权限,分别可以作用在多个层次上。
    1. grant 作用在整个 MySQL 服务器上:
    grant select on *.* to dba@localhost; -- dba 可以查询 MySQL 中所有数据库中的表。
    grant all on *.* to dba@localhost; -- dba 可以管理 MySQL 中的所有数据库
    2. grant 作用在单个数据库上:
    grant select on testdb.* to dba@localhost; -- dba 可以查询 testdb 中的表。
    3. grant 作用在单个数据表上:
    grant select, insert, update, delete on testdb.orders to dba@localhost;
    4. grant 作用在表中的列上:
    grant select(id, se, rank) on testdb.apache_log to dba@localhost;
    5. grant 作用在存储过程、函数上:
    grant execute on procedure testdb.pr_add to ’dba’@’localhost’
    grant execute on function testdb.fn_add to ’dba’@’localhost’

    注意:修改完权限以后 一定要刷新服务,或者重启服务,刷新服务用:FLUSH PRIVILEGES。

    IDE工具介绍

    生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具,不能依赖这种ide

    掌握:
    1. 测试+链接数据库
    2. 新建库
    3. 新建表,新增字段+类型+约束
    4. 设计表:外键
    5. 新建查询
    6. 备份库/表
    
    注意:
    批量加注释:ctrl+?键
    批量去注释:ctrl+shift+?键

    pymysql模块

    dos命令安装
    pip3 install pymysql

    准备工作

    create database userinfo;
    use userinfo;
    create table regis(name char(10),password int(10));
    insert into regis values('xuxu',123456);

    建立链接、执行sql、关闭(游标)

    import pymysql
    user=input('用户名: ').strip()
    pwd=input('密码: ').strip()
    
    #链接
    conn=pymysql.connect(host='localhost',user='root',password='1234',database='userinfo',charset='utf8')
    #游标
    cursor=conn.cursor() #执行完毕返回的结果集默认以元组显示
    #cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)  #这种以字典的形式输出的可以很直观的看到字段和记录
    
    
    #执行sql语句
    sql='select * from regis where name="%s" and password="%s"' %(user,pwd) #注意%s需要加引号
    print(sql)
    res=cursor.execute(sql) #执行sql语句,返回sql查询成功的记录数目
    print(res)
    
    cursor.close()
    conn.close()
    
    if res:
        print('登录成功')
    else:
        print('登录失败')
    
    执行结果:
    用户名: xuxu
    密码: 123456
    select * from regis where name="xuxu" and password="123456"
    1
    登录成功

    execute()之sql注入

    注意:符号--会注释掉它之后的sql,正确的语法:--后至少有一个任意字符

    根本原理:就根据程序的字符串拼接name='%s',我们输入一个xxx' -- haha,用我们输入的xxx加'在程序中拼接成一个判断条件name='xxx' -- haha'

    最后那一个空格,在一条sql语句中如果遇到select * from t1 where id > 3 -- and name='xuxu';则--之后的条件被注释掉了
    
    1、sql注入之:用户存在,绕过密码
    xuxu' -- 任意字符
    
    2、sql注入之:用户不存在,绕过用户与密码
    xxx' or 1=1 -- 任意字符
    

    出现过的bug

    xxxx后面所跟的单引号或双引号要看你自己之前定义格式时所用的单引号或双引号
    
    --的两边都要有空格才行

    解决办法

    原来是我们对sql进行字符串拼接
     sql="select * from userinfo where name='%s' and password='%s'" %(user,pwd)
     print(sql)
     res=cursor.execute(sql)
    
    改写为(execute帮我们做字符串拼接,我们无需且一定不能再为%s加引号了)
    sql="select * from userinfo where name=%s and password=%s" #!!!注意%s需要去掉引号,因为pymysql会自动为我们加上
    res=cursor.execute(sql,[user,pwd]) #pymysql模块自动帮我们解决sql注入的问题,只要我们按照pymysql的规矩来。
    

    增、删、改:conn.commit()

    import pymysql
    #链接
    conn=pymysql.connect(host='localhost',user='root',password='123',database='egon')
    #游标
    cursor=conn.cursor()
    
    #执行sql语句
    #part1
    # sql='insert into userinfo(name,password) values("root","123456");'
    # res=cursor.execute(sql) #执行sql语句,返回sql影响成功的行数
    # print(res)
    
    #part2
    # sql='insert into userinfo(name,password) values(%s,%s);'
    # res=cursor.execute(sql,("root","123456")) #执行sql语句,返回sql影响成功的行数
    # print(res)
    
    #part3
    sql='insert into userinfo(name,password) values(%s,%s);'
    res=cursor.executemany(sql,[("root","123456"),("lhf","12356"),("eee","156")]) #执行sql语句,返回sql影响成功的行数
    print(res)
    
    conn.commit() #提交后才发现表中插入记录成功
    cursor.close()
    conn.close()
    

    查:fetchone,fetchmany,fetchall

    import pymysql
    #链接
    conn=pymysql.connect(host='localhost',user='root',password='123',database='egon')
    #游标
    cursor=conn.cursor()
    
    #执行sql语句
    sql='select * from userinfo;'
    rows=cursor.execute(sql) #执行sql语句,返回sql影响成功的行数rows,将结果放入一个集合,等待被查询
    
    # cursor.scroll(3,mode='absolute') # 相对绝对位置移动
    # cursor.scroll(3,mode='relative') # 相对当前位置移动
    res1=cursor.fetchone()
    res2=cursor.fetchone()
    res3=cursor.fetchone()
    res4=cursor.fetchmany(2)
    res5=cursor.fetchall()
    print(res1)
    print(res2)
    print(res3)
    print(res4)
    print(res5)
    print('%s rows in set (0.00 sec)' %rows)
    
    
    
    conn.commit() #提交后才发现表中插入记录成功
    cursor.close()
    conn.close()
    
    '''
    (1, 'root', '123456')
    (2, 'root', '123456')
    (3, 'root', '123456')
    ((4, 'root', '123456'), (5, 'root', '123456'))
    ((6, 'root', '123456'), (7, 'lhf', '12356'), (8, 'eee', '156'))
    rows in set (0.00 sec)
    '''
    

    获取插入的最后一条数据的自增ID

    import pymysql
    conn=pymysql.connect(host='localhost',user='root',password='123',database='egon')
    cursor=conn.cursor()
    
    sql='insert into userinfo(name,password) values("xxx","123");'
    rows=cursor.execute(sql)
    print(cursor.lastrowid) #在插入语句后查看
    
    conn.commit()
    
    cursor.close()
    conn.close()
    

      

  • 相关阅读:
    缠中说禅 摘选
    laravel中不使用 remember_token时退出报错,如何解决?
    关于Ubuntu拒绝root用户ssh远程登录
    laravel中类似于thinkPHP中trace功能
    js原生语法实现表格操作
    使用clear来清除localStorage保存对象的全部数据
    JS设置CSS样式的集中方式
    thinkphp两表联查并且分页
    生于忧患,死于安乐 (先秦:孟子及其弟子)
    在对年轻人最不友好的环境中,刘裕起于阡陌,成就霸业
  • 原文地址:https://www.cnblogs.com/596014054-yangdongsheng/p/9993725.html
Copyright © 2020-2023  润新知