Is this a good way to prevent CSRF?
是.这样做是为了强制客户端在表单上执行GET,然后才能对表单处理程序执行POST操作.这可以防止现代浏览器中的CSRF,因为浏览器会阻止客户端Javascript对外部域执行XHR GET请求,因此第三方无法在其网站上模仿您的表单并成功获得提交的有效令牌.
When another page is opened as well that sets the same $_SESSION variable, the previous (still open) page becomes invalid, how to prevent this?
允许多个令牌一次有效,在会话中保留一组有效令牌.或者,根本不存储令牌,而是使用令牌签名方案.我已经涉足并解释了here.备选方案2:只使用一个令牌进行整个会话,而不会使令牌失效. (在评论中向@SilverlightFox提示帽子)
For forms this method is clear, but how to handle normal links? Is it necessary to append the token to each link as well?
不需要.你只需要保护POST请求,因为大概只有POST请求才能改变敏感数据(wink wink nudge nudge,你坚持REST约定,对吧?!)XHR GET请求已被浏览器端阻止.