实现OAUTH协议 实现 QQ 第三方登录效果

1.OAuth的简述

OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全、开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是安全的。

1.主要的应用场景

1.目前很多网站集成了新浪微博,QQ等登录平台,这带来的好处是不言而喻的,只需要一个QQ号,就可以登录集成了qq登录的网站,

不用记住太多的用户名和密码,如果QQ能够一统江湖,对于用户将是大大的好事。

2.有时候希望访问授权平台的资源,也可以通过这样方式实现。

2.运行原理

image

 

 

步骤如下:

1.用户访问第三方应用。

2.访问授权方如QQ的授权界面。

3.用户在QQ登录界面上输入用户名密码,进行授权。

4.第三方应用获取授权信息。

 

在这个过程中,登录验证的操作都在授权方进行。如qq。

 

2.项目中遇到的问题

在客户端调用webservice的时候,我们比如需要获取某个用户的个人资料信息,我们会这样使用:

String getInfoByAccount(String account);

我们会传入帐号,这样就会带来一个问题,只要知道某人的帐号,别有用心的用户就会够着别人的帐号,获取别人的隐秘信息。

我想可以通过自己实现OAUTH的方式来自己实现一个。

实现的过程如下:

image

 

1.授权在第三方网站,点击授权方的登录界面,这个界面在授权服务器上。

2.输入用户名密码后,如果登录成功,将生成的token  跳转到第三方的验证程序上。

3.第三方的验证程序将token提交到授权端进行验证,验证成功后,则返回用户信息和token。

4.第三方程序将用户和token写入到session中。

 

5.写入后则代表第三方应用登录成功。

授权方代码实现:

image

 

1.登录成功后,将当前用户写入到一个缓存中,缓存的key,是刚生成的随机token,value 值 为IAuthUser。

 

2. 授权方对token进行验证。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String id=request.getParameter("uid");
        response.setContentType("text/json;charset=utf-8");
        
        IAuthService service=AppUtil.getBean(IAuthService.class);
        IAuthUser authuser= service.getByUid(id);
        if(authuser==null){
            response.getWriter().print("{result:-1,msg:"userNotFound"}");
        }
        else{
            boolean timeOut=authuser.isTimeOut();
            if(timeOut){
                response.getWriter().print("{result:-2,msg:"timeout"}");
            }
            else{
                IUser user=authuser.getUser();
                service.setAuth(user);
                String json="{result:0,id:""+user.getUserId()+"",account:""+user.getAccount()+"",fullname:""+user.getFullname()+""}";
                response.getWriter().print(json);
            }
        }
    }

3.第三方应用验证逻辑。

第三方程序提交token给授权方。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String returnUrl=request.getParameter("returnUrl");
        String uid=request.getParameter("uid");
        String data="uid="+ uid;
        
        String json= HttpUtil.sendData(url, data, "");
        
        JSONObject jsonObj=JSONObject.parseObject(json);
        if(jsonObj.getInteger("result")==0){
            String userId=jsonObj.getString("id");
            String account=jsonObj.getString("account");
            String fullname=jsonObj.getString("fullname");
            User user=new User(userId, account, fullname);
            request.getSession().setAttribute(User.CURRENT_USER, user);
            request.getSession().setAttribute(User.CURRENT_ID, uid);
            if(StringUtil.isNotEmpty(returnUrl)){
                response.sendRedirect(returnUrl);
            }
        }
        else{
            response.getWriter().print(json);
        }

 

解决webserivce调用问题

在调用serivce的时候,就不要传入account了,传入上下文的token即可, 根据token 就可以获取对应的账户信息,这样也就解决了 直接输入帐号的问题。

原文地址:https://www.cnblogs.com/yg_zhang/p/5860739.html