融云服务端用户注册获取Token之1002错误

错误信息如下:

{"url":"/user/getToken.json","code":1002,"errorMessage":"invalid App-Key."}

先看官网文档 融云sdk服务端-用户注册文档:https://docs.rongcloud.cn/v3/views/im/noui/guide/private/user/register/serverapi.html

我第一反应以为是app-key不对,然后仔细核对了app-key,发现并没有问题,而官网文档没有提供1002错误码的更多说明,所以emmm~~~百度走起。

之前有人说是因为https和http的原因 我从https换成http发现还是有问题(其实觉得应该和https没啥关系,但是没有找到原因 死马当活马医了给),也有其他博客说可能是url没有编码导致的,然后参数中的头像也进行了编码,测试发现还是上诉错误。

然后仔细研究了一些官方提供的接口文档,发现自己写错了!!!!注意看官方给的请求格式:

POST /user/getToken.json HTTP/1.1
Host: api-cn.ronghub.com
App-Key: uwd1c0sxdlx2
Nonce: 14314
Timestamp: 1408710653491
Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
Content-Type: application/x-www-form-urlencoded

userId=jlk456j5&name=Ironman&portraitUri=http%3A%2F%2Fabc.com%2Fmyportrait.jpg

key ,时间戳,签名,随机数这些是header,用户id,昵称,头像才是参数 而我之前都作为参数进行请求了,所以会出现1002错误。

附最新代码:

package com.net.api;

import java.util.List;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.net.entity.Users;
import com.net.mapper.UsersMapper;
import com.net.utils.HttpUtil;
import com.net.utils.RETINFO;
import com.net.utils.RandomUtil;
import com.net.utils.StringUtil;


/**
 * 用户相关业务
 * @author zhangq
 *
 */
@RestController
@RequestMapping("/api/users")
public class UsersController {

    
    //定义在配置文件中的属性名
	@Value("${rongyun.appKey}")
	private String appKey;
	@Value("${rongyun.appSecret}")
	private String appSecret;
	@Value("${photo_path}")
	private String photo_path;
	
	@Autowired
	UsersMapper usersMapper;
	
	//=============================  用户基础业务     =============================
	
	/**
	 * 微信登陆/注册
	 * 用户不存在则直接注册
	 * @param user 用户信息 unionid必传   openid=&unionid=&name=&photo=
	 * @return Map
	 */
	@RequestMapping("/wxlogin")
	public Object wxLogin(Users user){
		if(user == null || user.getUnionid() == null || user.getUnionid() ==""){
			return RETINFO.paramError();
		}
		//查询用户是否存在
		Users users = usersMapper.login(user.getUnionid());
		if(users == null){//用户不存在 执行注册
			return reg(user);
		}
		
		if(users.getState() != 0){
			return RETINFO.retmsg("用户账户被禁用,请联系客服处理");
		}
		//用户存在 返回用户信息
		return RETINFO.ret(users);
	}
	
	
	/**
	 * 注册账户
	 * @param user 用户基本信息 openid  unionid name photo
	 * @return Map
	 */
	private Object reg(Users user){
		if(user.getOpenid() == null || user.getName() == null || user.getPhoto() ==null
				|| user.getOpenid() == "" || user.getName() == "" || user.getPhoto() == "" ){
			return RETINFO.paramError();
		}
		if(!StringUtil.isNull(user.getPhoto())){
			//服务器可以后,用服务器的链接(默认头像)
			user.setPhoto(photo_path);
		}
		if(!StringUtil.isNull(user.getName())){
			//如果没有填写昵称的话,随机一个昵称
			user.setName(RandomUtil.getRandom(8));
		}else{
			StringUtil.filterEmoji(user.getName());
		}
		//微信注册
		usersMapper.insert(user);
		
		//注册融云
		String token = createRongYunUser(user.getId(), user.getName(), user.getPhoto());
		if(token != null && token != ""){
			//更新用户的 融云token
			int i = usersMapper.updToken(user.getId(),token);
			if(i==1){
				Users users = usersMapper.login(user.getUnionid());
				return RETINFO.ret(users);
			}
			//更新融云token失败 则删除融云用户 删除数据库注册用户 由于融云用户需要在控制台删除 所以此处不删除融云账户 只删除数据库数据
		}
		
		//注册融云失败 则删除数据库的用户
		usersMapper.deleteByPrimaryKey(user.getId());
		
		//注册失败 即登陆失败
		return RETINFO.error();
	}
	
	/**
	 * 编辑用户资料 性别不能为0 年龄不能小于0
	 * @param users 用户信息 
	 * @return Map
	 */
	@RequestMapping("/edit")
	public Object editUserInfo(Users users){
		if(users == null || users.getId() == null || users.getId().intValue()<=0 ||
				(users.getSex()!=null && users.getSex()==0)  || (users.getAge()!=null && users.getAge()<0)
				|| (users.getCity()!=null && (users.getLatitude()==null || users.getLongitude() ==null ))){
			return RETINFO.paramError();
		}
		//检查用户是否存在
		Users isUsers = usersMapper.selectByPrimaryKey(users.getId());
		if(isUsers == null)
			return RETINFO.retmsg("用户不存在");
		
		//编辑用户资料
		int i = usersMapper.editUsers(users);
		if(i==1){
			Users newUsers = usersMapper.selectByPrimaryKey(users.getId());
			if((users.getPhoto()!=null && users.getPhoto()!="") || (users.getName()!=null && users.getName()!="")){
				//编辑用户资料
				editRongYunUser(newUsers.getId(), newUsers.getName(), newUsers.getPhoto());
			}
			return RETINFO.ret(newUsers);
		}
		return RETINFO.error();
	}
	
	//============================= 融云业务 ====================================
	
	
	
	/**
	 * 注册融云账户
	 * @param userId	用户ID
	 * @param name		用户昵称
	 * @param portraitUri	用户头像
	 * @return 融云 token 
	 */
	public String createRongYunUser(Integer userId,String name,String portraitUri){
		String url = "http://api-cn.ronghub.com/user/getToken.json";
		try {
			//生成时间戳
			String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
			//生成随机数  不超过 18 个字符。
			String nonce=String.valueOf(Math.random() * 1000000);
			//生成签名
			//Signature (数据签名)计算方法:将系统分配的 App Secret、Nonce (随机数)、Timestamp (时间戳)三个字符串按先后顺序拼接成一个字符串并进行 SHA1 哈希计算
			StringBuilder toSign = new StringBuilder(appSecret).append(nonce).append(timestamp);
			String signature = DigestUtils.sha1Hex(toSign.toString());
			
			//拼接请求参数
			String res = HttpUtil.postHttp(appKey, timestamp, nonce, signature, name, userId,  URLEncoder.encode(portraitUri, "UTF-8" ), url);
			System.out.println(res);
			Map<String,Object> rmap  = JSON.parseObject(res);
	        System.out.println("code======="+ rmap.get("code"));
	        if(Integer.valueOf(rmap.get("code").toString()) == 200){
	        	System.out.println("token======="+rmap.get("token"));
	 	        return (String) rmap.get("token");
	        }
		} catch (Exception e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
		}
		return  "";
	}
	
	/**
	 * 编辑融云用户信息
	 * @param userId    用户ID
	 * @param name		用户昵称
	 * @param portraitUri 用户头像
	 * @return 请求状态返回码 如果报错则返回0(这个是自己返回给上层方法的 不是融云返回) 正常修改返回状态码200
	 */
	public Integer editRongYunUser(Integer userId,String name,String portraitUri){
		String url = "http://api-cn.ronghub.com/user/refresh.json";
		try {
			//生成时间戳
			String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
			//生成随机数  不超过 18 个字符。
			String nonce=String.valueOf(Math.random() * 1000000);
			//生成签名
			//Signature (数据签名)计算方法:将系统分配的 App Secret、Nonce (随机数)、Timestamp (时间戳)三个字符串按先后顺序拼接成一个字符串并进行 SHA1 哈希计算
			StringBuilder toSign = new StringBuilder(appSecret).append(nonce).append(timestamp);
			String signature = DigestUtils.sha1Hex(toSign.toString());
			
			//拼接请求参数
			String res = HttpUtil.postHttp(appKey, timestamp, nonce, signature, name, userId, URLEncoder.encode(portraitUri, "UTF-8" ), url);
			System.out.println(res);
			Map<String,Object> rmap  = JSON.parseObject(res);
	        System.out.println("code======="+ rmap.get("code"));
	        return (Integer) rmap.get("code");
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return  0;
		}
	}
	
}

HttpUtil代码:

/**
     * 封装请求
     * @param App_Key	融云app-key
     * @param Timestamp 时间戳
     * @param Nonce		随机数
     * @param Signature	签名
     * @param userName	用户昵称
     * @param userId	用户ID 唯一
     * @param userHead	用户头像
     * @param url		请求的接口地址
     * @return			String 请求返回的数据
     * @throws Exception
     */
    public static String postHttp(String App_Key,String Timestamp,String Nonce,String Signature,String userName,Integer userId,String userHead, String url) throws Exception {
    	StringBuffer res = new StringBuffer();
    	HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("App-Key", App_Key);
        httpPost.setHeader("Timestamp", Timestamp);
        httpPost.setHeader("Nonce", Nonce);
        httpPost.setHeader("Signature", Signature);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1);
        nameValuePair.add(new BasicNameValuePair("name", userName));//名称(例如使用这个功能的‘张三’)
        nameValuePair.add(new BasicNameValuePair("userId", userId.toString()));// 用户id(根据自己的项目,自己生成一个串就行,UUID就行)
        nameValuePair.add(new BasicNameValuePair("portraitUri", userHead));//头像(存储头像的路径)
        HttpResponse httpResponse = null;
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair, "utf-8"));
            httpResponse = httpClient.execute(httpPost);
            BufferedReader br = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
            String line = null;
            while ((line = br.readLine()) != null) {
                res.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("res=" + res.toString());
        return res.toString();
    }

参考其他博客:

https://blog.csdn.net/li416338592/article/details/100528325


版权声明:本文为qy_0626原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。