服务器Token不存储可以吗,由客户端每次带上Token,客户端各自存储Token
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了服务器Token不存储可以吗,由客户端每次带上Token,客户端各自存储Token相关的知识,希望对你有一定的参考价值。
参考技术A Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。两种使用方式:
用设备号/设备mac地址作为Token(推荐)
客户端:客户端在登录的时候获取设备的设备号/mac地址,并将其作为参数传递到服务端。
服务端:服务端接收到该参数后,便用一个变量来接收同时将其作为Token保存在数据库,并将该Token设置到session中,客户端每次请求的时候都要统一拦截,并将客户端传递的token和服务器端session中的token进行对比,如果相同则放行,不同则拒绝。
分析:此刻客户端和服务器端就统一了一个唯一的标识Token,而且保证了每一个设备拥有了一个唯一的会话。该方法的缺点是客户端需要带设备号/mac地址作为参数传递,而且服务器端还需要保存;优点是客户端不需重新登录,只要登录一次以后一直可以使用,至于超时的问题是有服务器这边来处理,如何处理看若服务器的Token超时后,服务器只需将客户端传递的Token向数据库中查询,同时并赋值给变量Token,如此,Token的超时又重新计时。
用session值作为Token
客户端:客户端只需携带用户名和密码登陆即可。
客户端:客户端接收到用户名和密码后并判断,如果正确了就将本地获取sessionID作为Token返回给客户端,客户端以后只需带上请求数据即可。
分析:这种方式使用的好处是方便,不用存储数据,但是缺点就是当session过期后,客户端必须重新登录才能进行访问数据。
Android使用token维持登陆状态的方法
什么是token
token(令牌)是一串唯一的字符串,通常由服务端生成,在注册完成时返回给客户端,用来标识此用户,客户端将此字符串存储在本地。在以后的网络请求时,客户端先查询本地的token,如果有则直接使用此令牌进行网络请求,没有则提示未登录,转到登陆注册界面。
此外,还可以在服务端或者客户端添加过期判别机制。
token的作用
token可以显著减少服务端对用户表的查询,同时使用户不必每次都登陆,提高了系统的可用性与健壮性。
使用SharedPreferences保存token
获取token并保存
NetWorks.regPost(user, password, email, tel, new Observer<User>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { Log.e("LoginActivity",e.getLocalizedMessage()+"--"+e.getMessage()); } @Override public void onNext(User user) { if(user.getmMessage().equals("success")){ MainActivity.instance.finish();//结束原来的主页面 Toast.makeText(getApplicationContext(),"注册成功",Toast.LENGTH_SHORT).show(); //token保存到本地 SharedPreferences sp = getSharedPreferences("loginToken", 0); SharedPreferences.Editor editor = sp.edit(); editor.putString("userId",user.getmUserId()); editor.putString("userName",user.getmUserName()); editor.putString("phone",user.getmPhone()); editor.putString("email",user.getmEmail()); editor.putString("headImageUrl",user.getmHeadImageUrl()); editor.commit(); Intent i = new Intent(RegActivity.this,MainActivity.class); startActivity(i); finish(); }else{ Toast.makeText(getApplicationContext(),"注册失败"+user.getmMessage(),Toast.LENGTH_SHORT).show(); } } });
我使用的是retrofit框架进行网络请求,上文是实现注册功能的函数,在onNext()函数中获取服务端返回的结果,这个框架自动把返回的json数据解析为对应的类对象(即上文中的user对象)。因为token的本质是唯一的字符串,userId满足这个要求,因为userId是由服务端生成且唯一,故我将userId作为token使用。
进行网络请求前查询本地token
比如点击侧边栏的头像,如果未登录则需要跳转到登陆界面,已经登陆则进入个人信息界面。这时候,就需要查询本地token进行判别。
private void initData() { sp = getSharedPreferences("loginToken", 0); name = sp.getString("userId", null); userName = sp.getString("userName", null); email = sp.getString("email", null); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.imageView: if (name == null) { Intent i = new Intent(MainActivity.this, LoginActivity.class); startActivity(i); } else { Log.d("用户ID", name); Intent i = new Intent(MainActivity.this, PersonInfoActivity.class); startActivity(i); } break; } }
备注
在此例中,我使用userId作为token,但并不建议这么做,虽然这样很简单。因为userId显然无法判别是否过期,如果我们需要实现token过期的判别,则可以采用将userId与日期拼接的方式。
此外,为了安全起见,不要在客户端生成token。
以上是关于服务器Token不存储可以吗,由客户端每次带上Token,客户端各自存储Token的主要内容,如果未能解决你的问题,请参考以下文章