zoukankan      html  css  js  c++  java
  • 第六十三篇 用户权限、pymysql模块

    一、用户管理

    1.用户权限

    1.方法:

    • 将用户信息写入表中即可

    2.权限相关表:

    # 自带的MySQL库中,有以下四个表用于存储用户信息以及权限
    
    user   # 所有用户信息都会存储在里面,无论权限有多少
    
    db     # 存放拥有对库操作的权限的用户信息
    
    table_priv   # 存放仅拥有对表操作的权限的用户信息
    
    columns_priv  # 存储仅拥有对字段操作权限的用户信息
    
    # 权限优先级
    user -> db -> table_priv -> columns_priv
    
    # 查看表中内容,由于字段太多,以表格形式展示会比较乱,可以添加G来纵向显示
    select * from user G;  # 可以查看用户所拥有的权限
    

    3.操作权限:

    • 可以通过select/update/delete/insert/drop等等,设置操作权限

    2.授权

    1.创建用户和删除用户

    # 创建用户时,需要三个信息:账户名、IP地址、密码
    
    # 其中IP地址是用来限制该账户的登陆设备的,也就是让其只能在指定的机器上登陆
    # 我们可以用通配符"%"来表示可以在任意IP地址端的计算机上登陆(不包括主机地址)
    # 要想包括主机,我们任然需要加上:create user 用户名@'127.0.0.1' identified by '密码';
    # 注意:主机IP可以用localhost代替
    
    # 语法:
    create user 用户名@IP地址 identified by '密码';
    
    # 只有root账户可以创建用户(有其他方法可以让超级用户也获得该权限)
    # 在下面会讲
    
    # 删除用户(会同时删除其所有权限)
    drop user 用户名@IP地址;
    

    2.权限管理

    1.授权给用户,可以自由选择对创建用户的权限设置
    2.用这种方法时,其实也覆盖了创建用户的操作,因此一般直接用这种方法进行创建用户并授权

    # 1.给创建用户授权:可以对所有库、所有表、所有字段进行增删改查操作
    grant all on *.* to 用户名@IP地址 identified by '密码';
    
    # all表示对所有字段拥有增删改查的权限
    # *.*中第一个*表示所有库,第二个*表示所有表
    
    
    # 2.创建拥有和root用户一样权限的超级用户,并且可以在任何主机上登陆
    # with grant option表示可以将root所拥有的权限授予其他用户
    grant all on *.* to 用户名@"%" identified by '密码' with grant option;
    grant all on *.* to 用户名@localhost identified by '密码' with grant option;  # 用来保证在localhost也可以登陆该账户
    
    
    # 3.设置相应的权限
    # 3.1 授权可以操作指定库中的任何表的操作权限
    grant all on 库名.* to 用户名@IP地址 identified by '密码';
    grant all on mydb.* to 'king'@'%' identified by '123';
    select * from db G;
    
    # 3.2 授权指定库中指定表的操作权限(可以精确到操作级别)
    grant all on 库名.表名 to 用户名@IP地址 identified by '密码';
    grant all on mydb.emp to 'jojo'@'127.0.0.1' identified by '222';
    
    grant select on mydb.student to 'Timor'@'127.0.0.1' identified by '666' -- 只能对该表进行查看;
    select * from tables_priv G  -- 查看是否存在该用户; 
    
    # 3.3 授权指定库中指定表中的某个字段的操作权限(精确到字段和操作级别,不能使用*来表示对所有字段的操作限制)
    grant select(字段) on 库名.表名 to 用户名@IP地址 identified by  '密码';
    grant update(name) on mydb.emp to 'liu'@'192.151.11.201' identified by '333' -- 只能更新name字段的信息;
    select * from columns_priv G;
    
    
    # 4.刷新权限
    flush privileges;
    
    
    # 5.收回权限
    revoke all privileges 字段名 on 库名.表名 from 用户名@IP地址;
    revoke all on *.* from 用户名@IP地址;
    

    二、可视化MySQL软件(客户端)

    1.MySQL-workbench

    三、pymysql模块

    pymysql是python提供的一个mysql客户端模块,用于与mysql服务器建立连接,发送查询,并获取结果等

    1.简单的对库操作

    import pymysql
    
    try:
    	# 1.建立连接,并获得连接对象
    	conn = pymysql.Connect(
    		host = '127.0.0.1',
    		port = 3306,
    		user = 'root',
    		password = '',
    		db = 'mydb',
    	)
    	print('连接服务器成功')
    	
    	# 2.获取游标对象
    	cursor = conn.cursor(pymysql.cursors.DictCursor)  # 如果不加任何参数,则提取结果显示的是元组类型,使用pymysql.cursors.DictCursor,可以更换为字典类型的游标
    	
    	# 3.定制SQL语句
    	sql = 'select * from student'  # 里面不用加分号
    	
    	# 4.发送SQL语句,并得到搜索结果的个数
    	count = cursor.execute(sql)  
    	print(f'结果个数:{count}')
    	
    	# 5.提取结果(通过游标对象)
    	print(cursor.fetchall())  # 提取全部结果
    	print(cursor.fetchmany(2))  # 通过参数,提取指定个数的结果
    	print(cursor.fetchone())  # 仅提取一个结果
    	
    	# 6.移动游标,可以多次提取结果
    	# 使用相对位置
    	# 游标当前所在位置的值的索引是0,可以正负数字来移动游标
    	cursor.scroll(-1, 'relative')  # 游标当前所在位置向前(左)移动一位
    	print(cursor.fetchone())
    	cursor.scroll(1, 'realative') # 游标向当前位置的后面(右)移动一位
    	print(cursor.fetchone())
    	
    	# 使用绝对位置
    	# 规定了所有值的索引,第一个值的索引是0,依次累加,游标根据索引来查找值的位置
    	cursor.scroll(1, 'absolute')  # 游标指向索引为1的值
    	print(cursor.fetchone())
    
    # 7.捕获异常
    except Exception as e:
    	print('连接服务器失败')
    	print(e)
    
    finally:     # 无论如何后面的代码都会执行
    
    	# 8.关闭游标
    	if cursor:
    		cursor.close()
    		print('关闭游标')
    		
    	# 9.关闭连接
    	if conn:
    		conn.close()
    		print('关闭连接')
    

    2.SQL注入攻击

    1.通过按照SQL语法来编写带有攻击目的的SQL语句作为参数,插入到原始语句中,让数据库执行,进而导致数据库中的数据不安全

    2.案例:

    • 2.1 存在的问题
    # 登陆示例:
    # 1.连接服务器
    # 2.用户认证(在数据库中进行)
    # 3.发送指令
    # 4.提取结果
    import pymysql
    
    try:
    	conn = pymysql.Connect(
    		host = '127.0.0.1',  # 如果是本机,则可以忽略
    		port = 3306,    # 如果没改过,可以忽略
    		user = 'root',
    		password = '123',
    		database = 'mydb'
    	)
    	
    	cursor = conn.cursor(pymysql.cursor.DictCursor)
    	
    	login_username = input('username>>>')
    	login_password = input('password>>>')
    	
    	sql = "select * from login where name = '%s' and password = '%s'" %(login_username, login_password)
    	
    	count = cursor.execute(sql)
    	
    	if count:
    		print('ok')
    	else:
    		print('error')
    		
    except Exception as e:
    	print(e)
    
    finally:
    	if cursor: cursor.close()
    	
    	if conn: conn.close()
    	
    	'''尝试在用户名中输入以下内容,密码随意
     		jerry' — ass 
    		或者连用户名都不用写
    		' or 1 = 1 -- asaa
    	'''
    
    • 2.2 解决方案:
    # 1.客户端在发送sql给服务器前进行re判断,这样的问题在于一些程序可以模拟客户端直接发送请求给服务器
    
    # 2.在服务器端将sql交给mysql是作进一步处理,相关的代码其实pymysql已经做了封装
    
    # 3.我们只要保证不要自己来拼接sql语句即可,将拼接参数操作交给pymysql.
    
    try:
        conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",)
        print("连接服务器成功!")
        cursor = conn.cursor(pymysql.cursors.DictCursor)
        
        user = input("username:")
        password = input("password:")
    
        sql = "select *from user where name = %s and password = %s"
        print(sql)
        count = cursor.execute(sql,(user,password)) # 参数交给模块
        if count:
            print("登录成功!")
        else:
            print("登录失败!")
    except Exception as e:
        print(type(e),e)
    finally:
        if cursor: cursor.close()
        if conn: conn.close()
    

    3.编写注册:

    # 注意: pymysql自动开启了事务,所以我们自己在合适的位置提交
    
    import pymysql
    conn = pymysql.connect(
        host = "127.0.0.1",  #如果是本机 可以忽略
        port = 3306,    # 如果没改过 可以忽略
        user = "root", #必填
        password = "111", #必填
        database = "day42", #必填,
        #autocommit=False  # 开启自动提交  不常用....
    )
    
    c = conn.cursor(pymysql.cursors.DictCursor)
    
    
    name = input("name:")
    pwd = input("pwd:")
    
    sql = "select *from user where name = %s"
    
    if c.execute(sql,(name,)):
        print("用户名已存在!")
    else:
        sql2 = "insert  into user values(%s,%s)"
        if c.execute(sql2,(name,pwd)):
            print("注册成功!")
            conn.commit() # 调用连接对象的提交函数
        else:
            print("注册失败!")
    
    c.close()
    conn.close()
    

    3.pymysql对于事务的应用

    import pymysql
    conn = pymysql.connect(
        host = "127.0.0.1",  #如果是本机 可以忽略
        port = 3306,    # 如果没改过 可以忽略
        user = "root", #必填
        password = "111", #必填
        database = "day42", #必填,
        autocommit=True  # 开启自动提交  不常用....
    )
    c = conn.cursor(pymysql.cursors.DictCursor)
    
    try:
        c.execute("start transaction;")
        sql1 = "update user set money = money - 1000 where name = 'jack'"
        c.execute(sql1)
        sql2 = "update user set moneys = money + 1000 where name = 'rose'"
        c.execute(sql2)
        c.execute("commit;")
    except:
        c.execute("rollback;")
    
    
    c.close()
    conn.close()
    
    

    4.pymysql对于存储过程的应用

    # 创建名为add1的存储过程
    delimiter |
    create procedure add1(in a int,in b int,out c int)
    begin
    set c = a + b;
    end|
    delimiter ;
    
    import pymysql
    conn = pymysql.connect(
        host = "127.0.0.1",  #如果是本机 可以忽略
        port = 3306,    # 如果没改过 可以忽略
        user = "root", #必填
        password = "111", #必填
        database = "day42", #必填,
        autocommit=True  # 开启自动提交  不常用....
    )
    c = conn.cursor(pymysql.cursors.DictCursor)
    
    res = c.callproc("add1",(1,2,1212)) # @_add1_0  @_add1_1  @_add1_2
    c.execute("select @_add1_2")
    print(c.fetchone())
    # 调用存储过程时,传入参数,会自动定义成变量,
    
    # 命名方式 @_过程的名称_参数的索引 从0开始
    
  • 相关阅读:
    B树与B+详解
    SQLite占用资源少原因
    iOS SQLite详解
    YTKNetwork网络封装
    YTKNetwork源码详解
    AFNetworking封装-项目使用
    iOS网络请求-AFNetworking源码解析
    PHP 不使用第三个变量实现交换两个变量的值
    PHP public private protected 三种修饰符的区别
    PHP 汉字转拼音
  • 原文地址:https://www.cnblogs.com/itboy-newking/p/11276854.html
Copyright © 2011-2022 走看看