小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

第六十三篇 用戶權(quán)限、pymysql模塊

 印度阿三17 2019-07-31

目錄

一、用戶管理

1.用戶權(quán)限

1.方法:

  • 將用戶信息寫入表中即可

2.權(quán)限相關(guān)表:

# 自帶的MySQL庫(kù)中,有以下四個(gè)表用于存儲(chǔ)用戶信息以及權(quán)限

user   # 所有用戶信息都會(huì)存儲(chǔ)在里面,無(wú)論權(quán)限有多少

db     # 存放擁有對(duì)庫(kù)操作的權(quán)限的用戶信息

table_priv   # 存放僅擁有對(duì)表操作的權(quán)限的用戶信息

columns_priv  # 存儲(chǔ)僅擁有對(duì)字段操作權(quán)限的用戶信息

# 權(quán)限優(yōu)先級(jí)
user -> db -> table_priv -> columns_priv
# 查看表中內(nèi)容,由于字段太多,以表格形式展示會(huì)比較亂,可以添加\G來(lái)縱向顯示
select * from user \G;  # 可以查看用戶所擁有的權(quán)限

3.操作權(quán)限:

  • 可以通過(guò)select/update/delete/insert/drop等等,設(shè)置操作權(quán)限

2.授權(quán)

1.創(chuàng)建用戶和刪除用戶

# 創(chuàng)建用戶時(shí),需要三個(gè)信息:賬戶名、IP地址、密碼

# 其中IP地址是用來(lái)限制該賬戶的登陸設(shè)備的,也就是讓其只能在指定的機(jī)器上登陸
# 我們可以用通配符"%"來(lái)表示可以在任意IP地址端的計(jì)算機(jī)上登陸(不包括主機(jī)地址)
# 要想包括主機(jī),我們?nèi)稳恍枰由希篶reate user 用戶名@'127.0.0.1' identified by '密碼';
# 注意:主機(jī)IP可以用localhost代替

# 語(yǔ)法:
create user 用戶名@IP地址 identified by '密碼';

# 只有root賬戶可以創(chuàng)建用戶(有其他方法可以讓超級(jí)用戶也獲得該權(quán)限)
# 在下面會(huì)講

# 刪除用戶(會(huì)同時(shí)刪除其所有權(quán)限)
drop user 用戶名@IP地址;

2.權(quán)限管理

1.授權(quán)給用戶,可以自由選擇對(duì)創(chuàng)建用戶的權(quán)限設(shè)置
2.用這種方法時(shí),其實(shí)也覆蓋了創(chuàng)建用戶的操作,因此一般直接用這種方法進(jìn)行創(chuàng)建用戶并授權(quán)

# 1.給創(chuàng)建用戶授權(quán):可以對(duì)所有庫(kù)、所有表、所有字段進(jìn)行增刪改查操作
grant all on *.* to 用戶名@IP地址 identified by '密碼';

# all表示對(duì)所有字段擁有增刪改查的權(quán)限
# *.*中第一個(gè)*表示所有庫(kù),第二個(gè)*表示所有表


# 2.創(chuàng)建擁有和root用戶一樣權(quán)限的超級(jí)用戶,并且可以在任何主機(jī)上登陸
# with grant option表示可以將root所擁有的權(quán)限授予其他用戶
grant all on *.* to 用戶名@"%" identified by '密碼' with grant option;
grant all on *.* to 用戶名@localhost identified by '密碼' with grant option;  # 用來(lái)保證在localhost也可以登陸該賬戶


# 3.設(shè)置相應(yīng)的權(quán)限
# 3.1 授權(quán)可以操作指定庫(kù)中的任何表的操作權(quán)限
grant all on 庫(kù)名.* to 用戶名@IP地址 identified by '密碼';
grant all on mydb.* to 'king'@'%' identified by '123';
select * from db \G;

# 3.2 授權(quán)指定庫(kù)中指定表的操作權(quán)限(可以精確到操作級(jí)別)
grant all on 庫(kù)名.表名 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' -- 只能對(duì)該表進(jìn)行查看;
select * from tables_priv \G  -- 查看是否存在該用戶; 

# 3.3 授權(quán)指定庫(kù)中指定表中的某個(gè)字段的操作權(quán)限(精確到字段和操作級(jí)別,不能使用*來(lái)表示對(duì)所有字段的操作限制)
grant select(字段) on 庫(kù)名.表名 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.刷新權(quán)限
flush privileges;


# 5.收回權(quán)限
revoke all privileges 字段名 on 庫(kù)名.表名 from 用戶名@IP地址;
revoke all on *.* from 用戶名@IP地址;

二、可視化MySQL軟件(客戶端)

1.MySQL-workbench

三、pymysql模塊

pymysql是python提供的一個(gè)mysql客戶端模塊,用于與mysql服務(wù)器建立連接,發(fā)送查詢,并獲取結(jié)果等

1.簡(jiǎn)單的對(duì)庫(kù)操作

import pymysql

try:
    # 1.建立連接,并獲得連接對(duì)象
    conn = pymysql.Connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '',
        db = 'mydb',
    )
    print('連接服務(wù)器成功')
    
    # 2.獲取游標(biāo)對(duì)象
    cursor = conn.cursor(pymysql.cursors.DictCursor)  # 如果不加任何參數(shù),則提取結(jié)果顯示的是元組類型,使用pymysql.cursors.DictCursor,可以更換為字典類型的游標(biāo)
    
    # 3.定制SQL語(yǔ)句
    sql = 'select * from student'  # 里面不用加分號(hào)
    
    # 4.發(fā)送SQL語(yǔ)句,并得到搜索結(jié)果的個(gè)數(shù)
    count = cursor.execute(sql)  
    print(f'結(jié)果個(gè)數(shù):{count}')
    
    # 5.提取結(jié)果(通過(guò)游標(biāo)對(duì)象)
    print(cursor.fetchall())  # 提取全部結(jié)果
    print(cursor.fetchmany(2))  # 通過(guò)參數(shù),提取指定個(gè)數(shù)的結(jié)果
    print(cursor.fetchone())  # 僅提取一個(gè)結(jié)果
    
    # 6.移動(dòng)游標(biāo),可以多次提取結(jié)果
    # 使用相對(duì)位置
    # 游標(biāo)當(dāng)前所在位置的值的索引是0,可以正負(fù)數(shù)字來(lái)移動(dòng)游標(biāo)
    cursor.scroll(-1, 'relative')  # 游標(biāo)當(dāng)前所在位置向前(左)移動(dòng)一位
    print(cursor.fetchone())
    cursor.scroll(1, 'realative') # 游標(biāo)向當(dāng)前位置的后面(右)移動(dòng)一位
    print(cursor.fetchone())
    
    # 使用絕對(duì)位置
    # 規(guī)定了所有值的索引,第一個(gè)值的索引是0,依次累加,游標(biāo)根據(jù)索引來(lái)查找值的位置
    cursor.scroll(1, 'absolute')  # 游標(biāo)指向索引為1的值
    print(cursor.fetchone())

# 7.捕獲異常
except Exception as e:
    print('連接服務(wù)器失敗')
    print(e)

finally:     # 無(wú)論如何后面的代碼都會(huì)執(zhí)行

    # 8.關(guān)閉游標(biāo)
    if cursor:
        cursor.close()
        print('關(guān)閉游標(biāo)')
        
    # 9.關(guān)閉連接
    if conn:
        conn.close()
        print('關(guān)閉連接')

2.SQL注入攻擊

1.通過(guò)按照SQL語(yǔ)法來(lái)編寫帶有攻擊目的的SQL語(yǔ)句作為參數(shù),插入到原始語(yǔ)句中,讓數(shù)據(jù)庫(kù)執(zhí)行,進(jìn)而導(dǎo)致數(shù)據(jù)庫(kù)中的數(shù)據(jù)不安全

2.案例:

  • 2.1 存在的問(wèn)題
# 登陸示例:
# 1.連接服務(wù)器
# 2.用戶認(rèn)證(在數(shù)據(jù)庫(kù)中進(jìn)行)
# 3.發(fā)送指令
# 4.提取結(jié)果
import pymysql

try:
    conn = pymysql.Connect(
        host = '127.0.0.1',  # 如果是本機(jī),則可以忽略
        port = 3306,    # 如果沒(méi)改過(guò),可以忽略
        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()
    
    '''嘗試在用戶名中輸入以下內(nèi)容,密碼隨意
        jerry' — ass 
        或者連用戶名都不用寫
        ' or 1 = 1 -- asaa
    '''
  • 2.2 解決方案:
# 1.客戶端在發(fā)送sql給服務(wù)器前進(jìn)行re判斷,這樣的問(wèn)題在于一些程序可以模擬客戶端直接發(fā)送請(qǐng)求給服務(wù)器

# 2.在服務(wù)器端將sql交給mysql是作進(jìn)一步處理,相關(guān)的代碼其實(shí)pymysql已經(jīng)做了封裝

# 3.我們只要保證不要自己來(lái)拼接sql語(yǔ)句即可,將拼接參數(shù)操作交給pymysql.

try:
    conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="",db="day46",)
    print("連接服務(wù)器成功!")
    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)) # 參數(shù)交給模塊
    if count:
        print("登錄成功!")
    else:
        print("登錄失敗!")
except Exception as e:
    print(type(e),e)
finally:
    if cursor: cursor.close()
    if conn: conn.close()

3.編寫注冊(cè):

# 注意: pymysql自動(dòng)開啟了事務(wù),所以我們自己在合適的位置提交

import pymysql
conn = pymysql.connect(
    host = "127.0.0.1",  #如果是本機(jī) 可以忽略
    port = 3306,    # 如果沒(méi)改過(guò) 可以忽略
    user = "root", #必填
    password = "111", #必填
    database = "day42", #必填,
    #autocommit=False  # 開啟自動(dòng)提交  不常用....
)

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("注冊(cè)成功!")
        conn.commit() # 調(diào)用連接對(duì)象的提交函數(shù)
    else:
        print("注冊(cè)失敗!")

c.close()
conn.close()

3.pymysql對(duì)于事務(wù)的應(yīng)用

import pymysql
conn = pymysql.connect(
    host = "127.0.0.1",  #如果是本機(jī) 可以忽略
    port = 3306,    # 如果沒(méi)改過(guò) 可以忽略
    user = "root", #必填
    password = "111", #必填
    database = "day42", #必填,
    autocommit=True  # 開啟自動(dòng)提交  不常用....
)
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對(duì)于存儲(chǔ)過(guò)程的應(yīng)用

# 創(chuàng)建名為add1的存儲(chǔ)過(guò)程
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",  #如果是本機(jī) 可以忽略
    port = 3306,    # 如果沒(méi)改過(guò) 可以忽略
    user = "root", #必填
    password = "111", #必填
    database = "day42", #必填,
    autocommit=True  # 開啟自動(dòng)提交  不常用....
)
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())
# 調(diào)用存儲(chǔ)過(guò)程時(shí),傳入?yún)?shù),會(huì)自動(dòng)定義成變量,

# 命名方式 @_過(guò)程的名稱_參數(shù)的索引 從0開始
來(lái)源:https://www./content-2-372451.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多