iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0
Modern Web

30天肝出購物網站系列 第 9

Day09:09 - User服務(4) - 前端 - JWT token、修改個人資料

Hola,我是Charlie!
在Day08當中,我們完成了後端的JWT機制還有修改個人資料,在今天我們將完成前端的JWT機制還有修改個人資料。

================================◉‿◉=================================

首先是註冊的部分,註冊的話加上儲存token跟username:

window.localStorage.setItem('username',this.username)
window.localStorage.setItem('token',response.data.data.token)

加上之後,註冊成功即可在localStorage上儲存:
https://ithelp.ithome.com.tw/upload/images/20210923/201416664h4uTyOmEr.png

接著我們可以在header component的地方加上判斷是否為登入狀態的程式碼,並加上v-show,如果登入過後就顯示特定區塊:

<template slot="button-content">
	<img src="@/assets/cart.svg" alt="購物車">
</template>
<div id="shoppingCart">
	<ul>
		<li>
			大魚
		</li>
		<li>
			小魚
		</li>
	</ul>
</div>
</b-nav-item-dropdown>
<b-nav-item-dropdown text="會員" right>
<b-dropdown-item href="/#/login" v-show="!isLogin">登入</b-dropdown-item>
<b-dropdown-item href="/#/register" v-show="!isLogin">註冊</b-dropdown-item>
<b-dropdown-item href="/#/self" v-show="isLogin">個人資料</b-dropdown-item>
<b-dropdown-item href="/#/order" v-show="isLogin">訂單</b-dropdown-item>
<b-dropdown-item v-show="isLogin">登出</b-dropdown-item>
</b-nav-item-dropdown>


<script>
  export default{
    name:'kheader',
    data(){
      return {
        isLogin:false,
        username:""
      }
    },
    mounted(){
      var username = window.localStorage.getItem('username')
      var token = window.localStorage.getItem('token')
      if(username != null && token != null){
        this.username = username
        this.isLogin = true
      }
    }
  }
</script>

新增完後到首頁查看,可以看到已經有變化了:
https://ithelp.ithome.com.tw/upload/images/20210923/20141666BHVGRtyByn.png

接著修改logout方法:

methods: {
  logout(){
    window.localStorage.removeItem('username')
    window.localStorage.removeItem('token')
    window.location.reload()
  }
}

接著修改登入頁面,一樣加上setItem:

login(data).then((response) => {
  if(response.data.code == STATUS_OK){
    window.localStorage.setItem('username',this.username)
    window.localStorage.setItem('token',response.data.data.token)
    this.$alert("登入成功").then(() => {
      window.location.href = '/#/index'
      window.location.reload()
    })
  }else{
    this.$fire({type:'error',text:response.data.data})
  }
})

https://ithelp.ithome.com.tw/upload/images/20210923/20141666kM1kto6VXk.png

接著在alert後面加上.then,設定重刷頁面,以註冊為例:

this.$alert("註冊成功").then(() => {
  window.location.href = "/#/index"
  window.location.reload()
})

接著是修改個人資料的部分,首先在django的users中建立GET方法判斷,要返回的是個人資料。

首先先加上路徑:

url(r'/(?P<username>[\w]{1,55})$',views.users)

接著加上request method,還有username參數:

@logincheck('PUT','DELETE','GET')
def users(request,username = None):

接著我們在User model中加上toJson方法:

def toJson(self):
	data = {}
	data["username"] = self.name
	data["password"] = ""
	data["phone"] = self.phone
	data["address"] = self.address
	data["created_time"] = self.created_time
	data["modified_time"] = self.modified_time
	return data

接著在users view中加入查詢的程式碼:

elif request.method == "GET":
	if username is None:
		return R.badRequest("UserName Not Found")
	user = User.objects.filter(name = username)
	if not user:
		return R.badRequest("user does not exist")
	user = user[0]
	data = user.toJson()
	return R.ok({"data":data})

並且使用POSTMAN測試:
https://ithelp.ithome.com.tw/upload/images/20210923/20141666XkM469rcSr.png

再來是前端的部分,首先在users.js中加入function:

export function getdata(username,token){
  return axios.get(`http://${host()}:${port()}/user/${username}`,{
    headers: {
      "AUTHORIZATION":token
    }
  })
}

接著在self.vue當中新增created程式碼:

created(){
  var username = window.localStorage.getItem('username')
  var token = window.localStorage.getItem('token')
  if(username != null && token != null){
    getdata(username,token).then((response) => {
      if(response.data.code == STATUS_OK){
        var rdata = response.data.data.data
        this.username = rdata.username
        this.phone = rdata.phone
        this.address = rdata.address
      }else{
        this.$fire({type:'error',text:response.data.data}).then(() => {
          window.location.href = "/#/login"
          window.location.reload()
        })
      }
    })
  }else{
    this.$fire({type:'error',text:"Please login"}).then(() => {
      window.location.href = "/#/login"
      window.location.reload()
    })
  }
}

接著是修改方法,先在users.js當中新增api接口:

export function fixdata(data,token){
  return axios.put(`http://${host()}:${port()}/user`,data,{
    headers:{
      "AUTHORIZATION":token
    }
  })
}

接著修改onSubmit方法:

onSubmit(){
	var data = {
	  "username":this.username,
	  "address":this.address,
	  "phone":this.phone
	}
	var token = window.localStorage.getItem('token')
	fixdata(data,token).then((response) => {
	  if(response.data.code == STATUS_OK){
	    this.$fire({type:'success',text:'更新成功'})
	  }else{
	    this.$fire({type:'error',text:response.data.data})
	  }
	})
}

** 如果這邊onSubmit方法失效的話,可改成@click **

就可以成功更新資料了。

再來是大頭貼的部分,首先新增Django models欄位:

avatar = models.ImageField(upload_to = "avatar/")

並且使用python manage.py makemigrations / migrate遷移:
https://ithelp.ithome.com.tw/upload/images/20210923/20141666bTDYsZDdt2.png

並在toJson內新增avatar欄位,這裡要使用的是url的部分:

data["avatar"] = self.avatar.url

接下來在users.js中新增uploadImage方法:

export function uploadImage(data,token){
  return axios.post(`http://${host()}:${port()}/user/avatar`,data,{
    headers:{
      "AUTHORIZATION":token,
      processData: false,
      contentType: false
    }
  })
}

** 這裡必須將processData跟contentType加入django的CORS白名單 **

後端的部分,檔案必須使用request.FILES,文字部分必須使用request.POST:

elif request.method == "POST" and 'avatar' in request.path:
	file = request.FILES.get('avatar')
	username = request.POST.get('username')
	user = User.objects.filter(name = username)
	if not user:
		return R.badRequest("User does not exist")
	user = user[0]
	user.avatar = file
	user.save()
	return R.ok("upload success")

前端的部分先在修改大頭貼前面加上b-form-file,並且加上修改方法:

<b-form-file v-model="avatar"></b-form-file>
<b-button variant="info" @click="uploadAvatar">修改大頭貼</b-button>

並且在methods當中新增uploadAvatar,設定upload後刷新:

uploadAvatar(){
	var token = window.localStorage.getItem('token')
	var username = window.localStorage.getItem('username')
	let formData = new FormData()
	formData.append('avatar',this.avatar)
	formData.append('username',username)
	uploadImage(formData,token).then((response) => {
	  if(response.data.code == STATUS_OK){
	    this.$fire({type:'success',text:'上傳成功'}).then(() => {
	      window.location.reload()
	    })
	  }else{
	    this.$fire({type:'error',text:response.data.data})
	  }
	})
},

接著在vue app裡面新增avatarURL model,並且在img src上綁定:

<img :src="'http://localhost:8000/media/avatar/' + avatarURL" alt="" style="max-width: 100%;max-height: 100%;">

就可以修改個人資料了。
https://ithelp.ithome.com.tw/upload/images/20210923/201416668XN8vJTde6.png

================================◉‿◉=================================

Day09結束了!在今天我們完成了修改個人資料,明天我們將開始商品區塊,See ya next day!


上一篇
Day08:08 - User服務(3) - 後端 - JWT token、修改個人資料
下一篇
Day10:10 - 商品服務(1) - 後端 - 總商品資料API
系列文
30天肝出購物網站30

尚未有邦友留言

立即登入留言